题意:给出一个无环图,求某个节点使得以它为根节点组成一棵树使得这棵树的深度达到最大。
思路:先用并查集判断是不是一个联通快,然后两遍DFS,第一次求出最深根是多少,第二次,求深度与其相等深度搜索深度相等的。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#define inf 0x3f3f3f3f
#define LL __int64
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
int n,j,cnt,head[100100],f[100010],sum;
bool vis[10100];
struct node{
int to,next;
}q[100100];
void Add(int a,int b){
q[cnt].to = b;
q[cnt].next = head[a];
head[a] = cnt++;
}
int fi(int x){
return x==f[x]?x:f[x] = fi(f[x]);
}
void mer(int a,int b){
int x = fi(a);
int y = fi(b);
x > y?f[x] = y:f[y] = x;
}
//230671 01481
int tmp[10000],ans1,ans2;
void dfs1(int u,int dp){
ans1 = max(ans1,dp);
for(int i = head[u];~i;i = q[i].next){
int v = q[i].to;
if(!vis[v]){
vis[v]= true;
dfs1(v,dp+1);
}
}
}
void dfs2(int u,int dp){
ans2 = max(ans2,dp);
for(int i = head[u];~i;i = q[i].next){
int v = q[i].to;
//cout<<v<<endl;
if(!vis[v]){
vis[v]= true;
dfs2(v,dp+1);
}
}
}
int main(){
int m,i,k,a,b;
while(~scanf("%d",&n)){
sum = cnt = 0;
memset(head,-1,sizeof(head));
for(i = 1;i <=n;++ i)
f[i] = i;
for(i = 0;i <n-1;++i){
scanf("%d%d",&a,&b);
Add(a,b);Add(b,a);
mer(a,b);
}
int ans = 0;
for(i = 1;i <=n;++ i){
if(f[i]==i)
ans++;
}
if(ans>=2){
printf("Error: %d components\n",ans);continue;
}
ans1 = ans2 = 0;
for(i = 1;i <=n;++ i){
memset(vis,false,sizeof(vis));
vis[i] = true;
dfs1(i,1);
}
for(i = 1;i <=n;++ i){
memset(vis,false,sizeof(vis));
ans2 = 0;
vis[i] = true;
dfs2(i,1);
if(ans1 == ans2){
printf("%d\n",i);
}
}
}
return 0;
}