1021 最深的根

发布时间 2023-04-21 20:16:34作者: 回忆、少年

一个无环连通图可以被视作一个树。

树的高度取决于所选取的根节点。

现在,你要找到可以使得树的高度最大的根节点。

它被称为最深的根。

输入格式

第一行包含整数 N,表示节点数量。

节点编号为 1N

接下来 N1 行,每行包含两个整数,表示两个节点之间存在一条边。

输出格式

输出最深的根的节点编号。

如果最深的根不唯一,则按照从小到大的顺序,将它们依次输出,每个占一行。

如果给定的图不是树,输出 Error: K components,其中 K 是图中连通分量的数量。

数据范围

1N10^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;
}