Warm up(tarjan缩点建树+树的直径)
程序员文章站
2022-04-01 17:43:43
...
/*
Warm up
HDU - 4612
https://vjudge.net/problem/HDU-4612
tarjan缩点建树+树的直径
注意!!! 有重边,有重边,有重边!!!
*/
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
using namespace std;
#define maxm 2000010
#define maxn 200010
struct Edge{
int v,next;
bool cnt;
bool cong;
}edgeI[maxm];
int headI[maxn];
int dfn[maxn],low[maxn];
int belong[maxn];
int du[maxn];
int cntI,total,block;
int dep[maxn];
vector<int> mp[maxn];
stack<int> st;
void addI(int u,int v,bool cong){
edgeI[cntI].v=v;
edgeI[cntI].cnt=false;
edgeI[cntI].cong=cong;
edgeI[cntI].next=headI[u];
headI[u]=cntI++;
}
void init(int n){
memset(headI,-1,sizeof headI);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
while(!st.empty()) st.pop();
memset(belong,0,sizeof belong);
cntI=total=block=0;
for(int i=0;i<=n;i++) mp[i].clear();
}
void tarjan(int u,int fa,bool cong){
dfn[u]=low[u]=++total;
st.push(u);
for(int i=headI[u];~i;i=edgeI[i].next){
int v=edgeI[i].v;
if(v==fa&&(!cong)) continue;
if(!dfn[v]){
tarjan(v,u,edgeI[i].cong);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
edgeI[i].cnt=true;
edgeI[i^1].cnt=true;
}
}else if(low[u]>dfn[v]){
low[u]=dfn[v];
}
}
if(low[u]==dfn[u]){
block++;
while(1){
int t=st.top();
st.pop();
belong[t]=block;
if(t==u) break;
}
}
}
void dfs(int u){
for(int i=0;i<mp[u].size();i++){
int v=mp[u][i];
if(dep[v]!=-1) continue;
dep[v]=dep[u]+1;
dfs(v);
}
}
void solve(int n){
tarjan(1,0,false);
for(int u=1;u<=n;u++){
for(int i=headI[u];~i;i=edgeI[i].next){
if(edgeI[i].cnt){
mp[belong[edgeI[i].v]].push_back(belong[u]);
//cout<<belong[edgeI[i].v]<<" "<<belong[u]<<endl;
}
}
}
memset(dep,-1,sizeof dep);
dep[1]=0;
dfs(1);
int k=1;
for(int i=1;i<=block;i++){
if(dep[i]>dep[k]) k=i;
}
memset(dep,-1,sizeof dep);
dep[k]=0;
dfs(k);
int ans=0;
for(int i=1;i<=block;i++){
ans=max(ans,dep[i]);
}
printf("%d\n", block-1-ans);
}
struct Node{
int u,v;
}node[maxm];
bool cmp(Node a,Node b){
if(a.u!=b.u) return a.u<b.u;
else return a.v<b.v;
}
int main(){
int n,m;
int u,v;
while(~scanf("%d %d", &n, &m)&&(n+m)){
init(n);
for(int i = 0;i < m;i++){
scanf("%d%d",&u,&v);
if(u==v)continue;
if(u>v)swap(u,v);
node[i].u = u;
node[i].v = v;
}
sort(node,node+m,cmp);
for(int i = 0;i < m;i++){
if(i == 0 || (node[i].u!=node[i-1].u || node[i].v != node[i-1].v)){
if(i < m-1 && (node[i].u==node[i+1].u && node[i].v == node[i+1].v)){
addI(node[i].u,node[i].v,true);
addI(node[i].v,node[i].u,true);
}
else{
addI(node[i].u,node[i].v,false);
addI(node[i].v,node[i].u,false);
}
}
}
solve(n);
}
return 0;
}
上一篇: 揭秘南北朝时期的盱眙之战,最后结果如何?
下一篇: 置换排列