A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤104) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N−1 lines follow, each describes an edge by given the two adjacent nodes' numbers.
Output Specification:
For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print Error: K components
where K
is the number of connected components in the graph.
Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:
Error: 2 components
思路:已知n个顶点,n-1条边,问是否能构成一颗n个节点的树,如果能 从中选出节点做为树根,使树的高度最大。输出满足要求的所有结点 ,首先对于构建的图应该判断其是否连通,通过并查集来判断,每读入一条边,判断其根是否相同,不同则加入到一个集合中,最终可通过判断集合数是否为1来判断给定的图是否相通。当图连通时,肯定能构成树,如何选择合适的根节点,使树的高度最大,可以任选一结点 进行遍历,获取此时的最深的根节点的集合(A),然后从集合A中任意一个节点出发遍历整个树, 获取能达到最深的节点B集合。A和B的并集就是使树最高的根节点。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
vector<int> G[maxn];
int n,a,b,fath[maxn];
bool root[maxn],vis[maxn];
int findf(int x)
{
int a=x;
while(x!=fath[x]) x=fath[x];
while(a!=fath[a])
{
int z=a;
a=fath[a];
fath[z]=x;
}
return x;
}
int maxh=0;
vector<int> vc,ans;
void dfs(int u,int h)
{
vis[u]=true;
if(h>maxh)
{
vc.clear();
vc.push_back(u);
maxh=h;
}
else if(h==maxh) vc.push_back(u);
for(int i=0;i<G[u].size();i++)
{
if(vis[G[u][i]]==false)
{
dfs(G[u][i],h+1);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) fath[i]=i;
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
int fa=findf(a),fb=findf(b);
if(fa!=fb) fath[fa]=fb;
}
int cnt=0;
for(int i=1;i<=n;i++) root[findf(i)]=true;
for(int i=1;i<=n;i++) cnt+=root[i];
if(cnt!=1) printf("Error: %d components",cnt);
else{
dfs(1,1);
ans=vc;
memset(vis,false,sizeof(vis));
dfs(vc[0],1);
for(int i=0;i<vc.size();i++)
{
ans.push_back(vc[i]);
}
sort(ans.begin(),ans.end());
printf("%d\n",ans[0]);
for(int i=1;i<ans.size();i++)
{
if(ans[i]!=ans[i-1])
printf("%d\n",ans[i]);
}
}
return 0;
}