PAT (Advanced Level) Practice 1021 Deepest Root (25 分)
A graph which is connected and acyclic can be considered a tree. The hight 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
先利用並查集求有幾個集合。。
然後用兩遍dfs。。
第一遍dfs任意一個點,求出最大深度點的集合x。。。
第二遍dfs最大深度的任意一個點,求出另一個最大深度點的集合y。。
求兩個集合的並集就是題目答案。。。
程式碼如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int maxn=10005; int n; int flag=0; int vis[maxn]; int len[maxn]; int is[maxn]; int a[maxn]; int Lenn=0; vector<int>ve[maxn]; int Find(int x) { if(x==a[x]) return x; return a[x]=Find(a[x]); } void unit(int x,int y) { int fx=Find(x); int fy=Find(y); if(fx!=fy) a[fx]=fy; } void init() { memset(vis,0,sizeof(vis)); memset(len,0,sizeof(len)); memset(is,0,sizeof(is)); } void dfs (int x,int height) { Lenn=max(Lenn,height); vis[x]=1; len[x]=height; for (int i=0;i<ve[x].size();i++) { int v=ve[x][i]; if(!vis[v]) { vis[v]=1; dfs(v,height+1); } } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) a[i]=i; for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); unit(x,y); ve[x].push_back(y); ve[y].push_back(x); } for (int i=1;i<=n;i++) if(a[i]==i) flag++; if(flag>1) printf("Error: %d components\n",flag); else { init(); dfs(1,0); int x; for (int i=1;i<=n;i++) if(len[i]==Lenn) { is[i]=1; x=i; } memset (vis,0,sizeof(vis)); memset (len,0,sizeof(len)); Lenn=0; dfs(x,0); for (int i=1;i<=n;i++) if(len[i]==Lenn) is[i]=1; for (int i=1;i<=n;i++) if(is[i]) printf("%d\n",i); } return 0; }