Warm up(tarjan缩点建树+树的直径)

/*
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;
}

发布了70 篇原创文章 · 获赞 22 · 访问量 6473

猜你喜欢

转载自blog.csdn.net/weixin_44410512/article/details/104255447
今日推荐