1021 Deepest Root

 大致题意就是给出N个结点 和 N-1条边,判断它们能否形成一棵N个结点的树?如果能就从中选出某个结点,使得整棵树的高度最大。输出所有 满足要求的可以作为根结点的结点。

思路:

第一步,由于连通且边数为 N-1 的图一定是一棵树。所以可以通过并查集判断图是否连通。

第二步,当图连通时,遍历每个顶点,并记录以该顶点作为根结点时,树的最大高度。

第三步,输出满足要求的 结点编号。

 1 #include<iostream>
 2 #include<vector>
 3 #include<map>
 4 using namespace std;
 5 const int maxn = 10010;
 6 
 7 int father[maxn];
 8 int isRoot[maxn] = {0};
 9 //第一步,初始化所有集合
10 void init(int n) {
11     for(int i = 1 ; i <= n; ++i)
12         father[i] = i;
13 }
14 //第二步,查找根结点
15 int findFather(int a) {
16     int b = a;//备份a
17     while(a != father[a]) //查找根结点
18         a = father[a];
19     while(b != father[b]) {//再次查找根结点,使查找路径上的所有结点都指向根结点
20         int t = b; //备份b
21         b = father[b];
22         father[t] = a;
23     }
24     return a;
25 }
26 //第三步,合并a,b所在集合
27 void Union(int a,int b) {
28     int fa = findFather(a);
29     int fb = findFather(b);
30     if(fa != fb)
31         father[fa] = fb;
32 }
33 //计算连通块的个数
34 int calculate(int n) {
35     int blocks = 0;
36     for(int i = 1; i <= n; ++i)
37         isRoot[findFather(i)] = 1;
38     for(int i = 1; i <= n; ++i)
39         blocks += isRoot[i];
40     return blocks;
41 }
42 vector<int> adj[maxn];//邻接表
43 bool visited[maxn] = {false};//标记定点是否被访问过数组
44 
45 int maxlevel = -1;
46 void DFS(int v,int level) { //遍历连通块
47     visited[v] = true;
48     if(maxlevel < level) maxlevel = level;
49     for(int i = 0 ; i < adj[v].size(); ++i) {
50         if(visited[adj[v][i]] == false)
51             DFS(adj[v][i],level+1);
52     }
53 }
54 
55 int main() {
56     int n,v1,v2;
57     cin>>n;
58     init(n);
59     for(int i = 0 ; i < n-1; ++i) {
60         cin>>v1>>v2;
61         adj[v1].push_back(v2);
62         adj[v2].push_back(v1);
63         Union(v1,v2); // 合并v1,v2所在的集合
64     }
65     int blocks = calculate(n);
66     if(blocks > 1) {
67         printf("Error: %d components\n",blocks);
68     } else {
69         map<int,int> ans;
70         int MAXLEVEL = -1;
71         for(int i = 1 ; i <= n; ++i) {
72             maxlevel = -1;
73             fill(visited+1,visited+1+n,false);// 初始化标记数组
74             DFS(i,1);
75             ans[i] = maxlevel; //记录以当前i为根结点时,数的最大高度
76             MAXLEVEL = max(MAXLEVEL,maxlevel);//更新 树的最大高度
77         }
78         for(auto it = ans.begin() ; it != ans.end(); ++it)
79             if(it->second == MAXLEVEL)
80                 printf("%d\n",it->first);
81     }
82     return 0;
83 }

 

posted @ 2020-03-07 09:21  tangq123  阅读(195)  评论(0)    收藏  举报