#include <cstdio>
#include <set>
using namespace std;
set<int> g[100010],temp,ans;
int father[100010];
//isroot[i]为true表示i为根节点
bool isroot[100010];
int findfather(int x)
{
int a=x;
while(father[x]!=x)
x=father[x];
while(father[a]!=a)
{
int z=a;
a=father[a];
father[a]=x;
}
return x;
}
void Union(int a,int b)
{
int faa=findfather(a);
int fab=findfather(b);
if(faa!=fab)
father[faa]=fab;
return;
}
//将所有节点的父节点对应isroot置为true(因为压缩了路径,若一个图连通,其余n-1个节点均有同一个父节点)
//之后计算isroot=true的节点个数,即为连通分量个数
int calblock(int n)
{
int block=0;
for(int i=1;i<=n;i++)
isroot[findfather(i)]=true;
for(int i=1;i<=n;i++)
{
if(isroot[i]==true)
block++;
}
return block;
}
int maxh=0;
//两次DFS,取并集
void DFS(int u,int height,int pre)
{
if(height>maxh)
{
temp.clear();
temp.insert(u);
maxh=height;
}
else if(height==maxh)
temp.insert(u);
for(set<int>::iterator it=g[u].begin();it!=g[u].end();it++)
{
//避免走回头路
if(*it==pre)
continue;
DFS(*it,height+1,u);
}
}
int main()
{
int a,b,n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
g[a].insert(b);
g[b].insert(a);
Union(a,b);
}
int block=calblock(n);
if(block!=1)
printf("Error: %d components\n",block);
else
{
DFS(1,1,-1);
ans=temp;
set<int>::iterator ansbegin=ans.begin();
DFS(*ansbegin,1,-1);
for(set<int>::iterator it=temp.begin();it!=temp.end();it++)
ans.insert(*it);
for(set<int>::iterator it=ans.begin();it!=ans.end();it++)
printf("%d\n",*it);
}
return 0;
}
PAT 1021 Deepest Root (25 分)
最新推荐文章于 2022-03-06 17:13:01 发布