1021 最深的根
一个无环连通图可以被视作一个树。
树的高度取决于所选取的根节点。
现在,你要找到可以使得树的高度最大的根节点。
它被称为最深的根。
输入格式
第一行包含整数 N,表示节点数量。
节点编号为 1∼N。
接下来 N−1 行,每行包含两个整数,表示两个节点之间存在一条边。
输出格式
输出最深的根的节点编号。
如果最深的根不唯一,则按照从小到大的顺序,将它们依次输出,每个占一行。
如果给定的图不是树,输出 Error: K components
,其中 K 是图中连通分量的数量。
数据范围
1≤N≤10^4
输入样例1:
5
1 2
1 3
1 4
2 5
输出样例1:
3
4
5
输入样例2:
5
1 3
1 4
2 5
3 4
输出样例2:
Error: 2 components
代码实现:
#include<iostream>
#include<cstring>
#include<set>
#include<algorithm>
using namespace std;
const int N=1e4+5;
int h[N],e[N*2],ne[N*2],idx,father[N],dist[N],res;
set<int>s;
int find(int x){
if(father[x]!=x)father[x]=find(father[x]);
return father[x];
}
void add(int x,int y){
e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}
void dfs(int x,int dis,int f){
dist[x]=max(dist[x],dis);
res=max(res,dist[x]);
for(int i=h[x];~i;i=ne[i]){
int j=e[i];
if(j==f)continue;
dfs(j,dis+1,x);
}
}
int main(){
int n;
cin>>n;
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++)father[i]=i;
for(int i=0;i<n-1;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
x=find(x),y=find(y);
father[x]=y;
}
int cnt=0;
for(int i=1;i<=n;i++)if(find(i)==i)cnt++;
if(cnt!=1)cout<<"Error: "<<cnt<<" components"<<endl;
else{
for(int i=1;i<=n;i++)dfs(i,1,0);
for(int i=1;i<=n;i++)if(dist[i]==res)s.insert(i);
for(auto t:s)cout<<t<<endl;
}
return 0;
}