1021 Deepest Root (25)(25 分)
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 (<=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
题意:给一个n个节点,n-1条边的图,判断有几个连通分量,若只有一个连通分量,求使得该图看作树时,树高最高的根节点。 使用邻接表存储图(感觉邻接矩阵存不下也浪费空间),并查集求连通分量个数,层序遍历求深度。牛客网测试数据严格些,不过都可以通过:
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
int parent[10001];
int visited[10001];
int root(int i){
while(parent[i]>=0)
i=parent[i];
return i;
}
void unionNode(int r1,int r2){
if(parent[r1]>parent[r2]){
parent[r2]+=parent[r1];parent[r1]=r2;
}else{
parent[r1]+=parent[r2];parent[r2]=r1;
}
}
int main(){
int n;
scanf("%d",&n);
vector<int> e[10001];
fill(parent,parent+10000,-1);
int r1,r2;
int e1,e2;
for(int i=0;i<n-1;i++){
scanf("%d %d",&e1,&e2);
e[e1].push_back(e2);
e[e2].push_back(e1);
r1=root(e1);
r2=root(e2);
if(r1!=r2)//构建并查集
unionNode(r1,r2);
}
int count=0;
for(int i=1;i<=n;i++){
if(parent[i]<0)
count++;
}
if(count!=1){
printf("Error: %d components",count);
return 0;
}
int deep=0,tag,l;
vector<int> roots;
for(int i=1;i<=n;i++){//分别求deep
if(e[i].size()>1)//必存在度为一的顶点,最深树根必在其中
continue;
queue<int> level;
tag=i;l=0;level.push(i);
fill(visited,visited+10000,false);
visited[i]=true;
while(!level.empty()){
int t=level.front();
level.pop();
for(auto it=e[t].begin();it!=e[t].end();it++){
if(!visited[*it]){//未访问邻接边入队
level.push(*it);
visited[*it]=true;
}
}
if(t==tag&&!level.empty()){
l++;tag=level.back();
}
}//while
if(l>deep){
deep=l;roots.clear();roots.push_back(i);
}else if(l==deep){
roots.push_back(i);
}
}
sort(roots.begin(),roots.end());
for(int i=0;i<roots.size();i++){
printf("%d\n",roots[i]);
}
return 0;
}