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个结点的树,如果能,从中选出一个点作为根节点,使整棵树的高度最大。输出所有满足要求的可以作为树根的结点。如果不能构成一棵树,就输出他有几个集合。
解题思路:
首先先判断是否可以构成一棵树,这个操作可以用并查集来实现。
确定图连通后,则确定了树,选择合适根结点使树高最大的做法为:
先任意选择一个结点,从该节点开始遍历整棵树,获取能达到的最深的结点,记为集合A;然后从集合A中任意一个结点出发遍历整棵树,获取能达到的最深顶点,记为结点集合B。集合A与B的并集就是所求结果。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e4+10;
int n,flag,maxn;
vector<int> rd[N];
vector<int> ans,temp;
int deep[N],father[N],vis[N];
int find(int x)
{
while(x!=father[x])
x=father[x];
return x;
}
void Union(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
father[fx]=fy;
}
}
void dfs(int x,int deep)
{
int flag=0;
for(int i=0;i<rd[x].size();i++)
{
int y=rd[x][i];
if(!vis[y])
{
flag=1;
vis[y]=1;
dfs(y,deep+1);
vis[y]=0;
}
}
if(!flag)
{
if(deep>maxn)
{
maxn=deep;
temp.clear();
temp.push_back(x);
}
if(deep==maxn)
temp.push_back(x);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=0;i<n-1;i++)
{
int a,b;
scanf("%d%d",&a,&b);
Union(a,b);
rd[a].push_back(b);
rd[b].push_back(a);
}
int sum=0;
for(int i=1;i<=n;i++)
{
if(father[i]==i)
sum++;
}
if(sum!=1)
{
printf("Error: %d components\n",sum);
return 0;
}
vis[1]=1;
maxn=0;
dfs(1,1);
ans=temp;
int pos=ans[0];
memset(vis,0,sizeof(vis));
vis[pos]=1;
dfs(pos,1);
for(int i=0;i<temp.size();i++)
ans.push_back(temp[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;
}