您的位置:首页 > 其它

pat 1021. Deepest Root (25)

2016-07-25 09:10 591 查看
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 calledthe deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) 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


解题关键:先用并查集判断是否为树,然后再求树的直径(先随便取一点进行深搜,然后记录所有的最远的点a1,a2,a3......,最后再任取一点ai再进行深搜,记录所有最远的点b1,b2,b3.........,再合并a1,a2,a3......和b1,b2,b3.......

为什么要合并a,b?      

查找最长根的时候,首先从一点进行深搜,把其中距离最远的点记录下来(可访问到所有顶点,因为已经保证是树),然后从这些最远点中任选一点再进行深度搜索,这个时候的所有最远点都是最长根,关键是第一遍dfs保存的最远点也是最长根,这个地方最难理解了,首先,若第一遍dfs后的最远根不在从1开始的同一条支路上(他们的最近公共祖先是1),这是这些点必定都会是将来的最长根这很明显,若第一遍dfs后的最远根在从1开始的同一条支路上(他们的最近公共祖先不是1记为f),则第二遍dfs时的最长根所在的dfs遍历序列必过f,所以此时的情况又可将f点看做第一种情况中的1节点类似。综上第一次与第二次dfs的合集才是最终结果。http://blog.csdn.net/iaccepted/article/details/20454519

输入样例:

5

1 2

1 3

2 4

2 5

输出样例

3

4

5

#include<iostream>
#include<string.h>
#include<stack>
#include<vector>
using namespace std;
#include<stdio.h>
#include<algorithm>
#include<queue>
#define MS(a,b) memset(a,b,sizeof(a))
vector<int>tree[30000];
int ans[10005],fa[10005],g[10005],j,mm,vis[10005];
int findx(int x)
{
int r=x;
if(r!=fa[r])
fa[r]=findx(fa[r]);
return fa[r];
}
void Union(int x,int y)
{
int tx,ty;
tx=findx(x);ty=findx(y);
if(tx!=ty)
fa[tx]=ty;
}
void dfs(int u,int depth)
{
int i;
if(tree[u].size()==0)return ;
for(i=0;i<tree[u].size();i++)
{
if(!ans[tree[u][i]])//如果该节点深度未知
{
ans[tree[u][i]]=depth;//记录该节点的深度。
dfs(tree[u][i],depth+1);//搜索该节点的子节点。
}
}
}
int main()
{
int n,a,b,i,num,c,d;
cin>>n;
for(i=1;i<=n;i++)
fa[i]=i;
for(i=1;i<n;i++)
{
cin>>a>>b;
tree[a].push_back(b);
tree[b].push_back(a);
Union(a,b);
}
num=0;
for(i=1;i<=n;i++)
if(fa[i]==i)num++;
if(num!=1)
printf("Error: %d components\n",num);
else
{  mm=-1;j=0;
MS(ans,0);
ans[1]=1;
dfs(1,2);
for(i=1;i<=n;i++)
{
if(mm<ans[i])
mm=ans[i],c=i;
}
for(i=1;i<=n;i++)
if(ans[i]==mm)
g[j++]=i;
MS(ans,0);
mm=-1;
ans[c]=1;
dfs(c,2);
for(i=1;i<=n;i++)
if(mm<ans[i])
mm=ans[i];
for(i=1;i<=n;i++)
if(ans[i]==mm)
g[j++]=i;
sort(g,g+j);
MS(vis,0);
for(i=0;i<j;i++)
if(!vis[g[i]])
{    vis[g[i]]=1;
printf("%d\n",g[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: