[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 1021 Deepest Root

PAT 甲级 1021 Deepest Root

PAT (Advanced Level) 1021. Deepest Root (25)

PAT-1021 Deepest Root (25 分) 并查集判断成环和联通+求树的深度

1021. Deepest Root (25)

1021 Deepest Root (25 分)