原题地址:http://www.patest.cn/contests/pat-a-practise/1021
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
解题思路:首先用dfs检查给定的图有几个连通分量。题目保证输入无环,则若连通分量只有一个时,可以确定结构为树。从树的任意一点出发,达到的最远距离的节点为此树的最深根。然后,从这些节点中任意一个出发能到达的最远节点亦为最深根。
代码如下:
#include <stdio.h>
#include <cstring>
#include <vector>
#define MAXN 10002
using namespace std;
//int G[MAXN][MAXN];
vector<int> g[MAXN];
int depth[MAXN];
int n;
int vis[MAXN];
int mark[MAXN];
int d_max;
int d_tmp;
int conn(int p,int q){
for(int i = 0; i < g[p].size(); i++)
if(g[p][i] == q) return 1;
return 0;
}
void dfs_d(int t){
vis[t] = 1;
d_tmp++;
depth[t] = d_tmp;
for(int i = 0 ; i < n; i++){
if(conn(t,i) && !vis[i]){
dfs_d(i);
}
}
if(d_tmp > d_max) d_max = d_tmp;
d_tmp--;
}
void deep(){
memset(vis, 0, sizeof(vis));
memset(mark, 0, sizeof(mark));
d_max = d_tmp = 0;
dfs_d(0);
int index = 0;
int max = 0;
for(int i = 0; i < n; i++){
if(max < depth[i]){max = depth[i]; index = i;}
}
for(int i = 0; i < n; i++){
if(max == depth[i]){mark[i] = 1;}
}
memset(vis, 0, sizeof(vis));
d_max = d_tmp = 0;
dfs_d(index);
depth[index] = d_max;
}
void dfs(int t){
vis[t] = 1;
for(int i = 0 ; i < n; i++)
if(conn(t,i) && !vis[i]) dfs(i);
}
int isTree(){
int count = 0;
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++){
if(!vis[i]){
dfs(i);
count++;
}
}
return count;
}
int main(){
freopen("1021.txt","r",stdin);
// memset(G,0,sizeof(G));
memset(depth,-1,sizeof(depth));
scanf("%d",&n);
for(int i = 0; i < n-1;i++){
int f, t;
scanf("%d%d",&f,&t);
g[t-1].push_back(f-1);
g[f-1].push_back(t-1);
}
int t = isTree();
if(t != 1){
printf("Error: %d components",t);
return 0;
}
deep();
for(int i = 0; i < n; i++)
if(d_max == depth[i] || mark[i] == 1) printf("%d\n", i+1);
return 0;
}