[PAT] A1021 Deepest Root
Posted yue36
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[PAT] A1021 Deepest Root相关的知识,希望对你有一定的参考价值。
【题目大意】
给出n个结点和n-1条边,问它们能否形成一棵n个结点的树,如果能,从中选出结点作为树根,使整棵树的高度最大。输出所有满足要求的可以作为树根的结点。
【思路】
方法一:模拟。
1 连通、边数为n-1的图一定是一棵树。因此先判断连通图个数(用DFS遍历图,从而计算连通图个数),等于1则能形成一棵树。
2 遍历每一个节点,假设它为根节点构造一棵树。
方法二:
1 由于连通、边数为n-1的图一定是一棵树,因此需要判断给定数据是否能使图连通。
2 确定图连通后,则确定了树,选择合适根结点使树高最大的做法为:
先任意选择一个结点,从该节点开始遍历整棵树,获取能达到的最深的结点,记为集合A;然后从集合A中任意一个结点出发遍历整棵树,获取能达到的最深顶点,记为结点集合B。集合A与B的并集就是所求结果。
https://blog.csdn.net/hy971216/article/details/82252707
https://blog.csdn.net/qq_38677814/article/details/80859998
https://blog.csdn.net/sinat_29278271/article/details/47934611
【tips】
1 非二叉树其实可以想象成一个特殊的图来解决。像这一题,用的其实全都是图的知识来解决,因为其考点不在父子关系上。
2 也可以使用并查集判断连通图个数(未实践过):每读入一条边的两个端点,判断这两个端点是否属于相同的集合,如果不同,则将它们合并到一个集合中,当处理完所有边后根据最终产生的集合个数是否为1来判断给定的图是否连通。
【AC代码】
方法一:
1 #include<iostream> 2 #include<queue> 3 #include<vector> 4 using namespace std; 5 #define N 10002 6 vector<int>G[N]; 7 int n; 8 int vis[N] = { false }; 9 int level[N] = { 0 }; 10 void DFS(int u) 11 { 12 for (int i = 0; i < G[u].size(); i++) 13 { 14 int v = G[u][i]; 15 if (vis[v] == false) 16 { 17 vis[v] = true; 18 DFS(v); 19 } 20 } 21 } 22 int BFS(int root) 23 { 24 int mlevel = 0; 25 queue<int>q; 26 q.push(root); 27 vis[root] = true; 28 while (!q.empty()) 29 { 30 int u = q.front(); 31 q.pop(); 32 for (int i = 0; i < G[u].size(); i++) 33 { 34 int v = G[u][i]; 35 if (vis[v] == false) 36 { 37 q.push(v); 38 vis[v] = true; 39 level[v] = level[u] + 1; 40 if (level[v] > mlevel) 41 mlevel = level[v]; 42 } 43 } 44 } 45 return mlevel; 46 } 47 int main() 48 { 49 cin >> n; 50 int i; 51 for (i = 0; i < n - 1; i++) 52 { 53 int t1, t2; 54 cin >> t1 >> t2; 55 G[t1].push_back(t2); 56 G[t2].push_back(t1); 57 } 58 int tu = 0; 59 for (i = 1; i <= n; i++) 60 { 61 if (vis[i] == false) 62 { 63 tu++; 64 vis[i] == true; 65 DFS(i); 66 } 67 } 68 if (tu > 1) 69 { 70 cout << "Error: " << tu << " components"; 71 return 0; 72 } 73 int maxLevel = 0; 74 vector<int>ans; 75 for (i = 1; i <= n; i++) 76 { 77 fill(vis, vis + N, false); 78 fill(level, level + N, false); 79 int ceng = BFS(i); 80 if (ceng == maxLevel) 81 { 82 ans.push_back(i); 83 } 84 if (ceng > maxLevel) 85 { 86 ans.clear(); 87 ans.push_back(i); 88 maxLevel = ceng; 89 } 90 } 91 for (i = 0; i < ans.size(); i++) 92 cout << ans[i] << endl; 93 94 return 0; 95 }
方法二:
1 #include<iostream> 2 #include<queue> 3 #include<vector> 4 #include<set> 5 using namespace std; 6 #define N 10002 7 vector<int>G[N]; 8 int n; 9 bool vis[N] = { false }; 10 int level[N] = { 0 }; 11 void DFS(int u) 12 { 13 for (int i = 0; i < G[u].size(); i++) 14 { 15 int v = G[u][i]; 16 if (vis[v] == false) 17 { 18 vis[v] = true; 19 DFS(v); 20 } 21 } 22 } 23 int BFS(int root) 24 { 25 int mlevel = 0; 26 queue<int>q; 27 q.push(root); 28 vis[root] = true; 29 while (!q.empty()) 30 { 31 int u = q.front(); 32 q.pop(); 33 for (int i = 0; i < G[u].size(); i++) 34 { 35 int v = G[u][i]; 36 if (vis[v] == false) 37 { 38 q.push(v); 39 vis[v] = true; 40 level[v] = level[u] + 1; 41 if (level[v] > mlevel) 42 mlevel = level[v]; 43 } 44 } 45 } 46 return mlevel; 47 } 48 int main() 49 { 50 cin >> n; 51 int i; 52 for (i = 0; i < n - 1; i++) 53 { 54 int t1, t2; 55 cin >> t1 >> t2; 56 G[t1].push_back(t2); 57 G[t2].push_back(t1); 58 } 59 int tu = 0; 60 for (i = 1; i <= n; i++) 61 { 62 if (vis[i] == false) 63 { 64 tu++; 65 vis[i] = true; 66 DFS(i); 67 } 68 } 69 if (tu > 1) 70 { 71 cout << "Error: " << tu << " components"; 72 return 0; 73 } 74 75 fill(vis, vis + N, false); 76 fill(level, level + N, 0); 77 int maxlevel = BFS(1); 78 set<int>ans; 79 for (i = 1; i <= n; i++) 80 if (level[i] == maxlevel) 81 ans.insert(i); 82 set<int>::iterator it = ans.begin(); 83 int v = *it; 84 fill(vis, vis + N, false); 85 fill(level, level + N, 0); 86 maxlevel = BFS(v); 87 for (i = 1; i <= n; i++) 88 if (level[i] == maxlevel) 89 ans.insert(i); 90 for (it = ans.begin(); it != ans.end(); it++) 91 cout << *it << endl; 92 93 return 0; 94 }
以上是关于[PAT] A1021 Deepest Root的主要内容,如果未能解决你的问题,请参考以下文章
PAT (Advanced Level) 1021. Deepest Root (25)