1021 Deepest Root——PAT甲级真题
1021 Deepest Root
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 (≤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
whereK
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
题目大意:让你求一棵树地最大深度,并找出能得到最大深度的结点有哪些。
大致思路:先用并查集判断一共有多少个连通块,如果连通块的个数>1说明不是一棵树,如果是一棵树则从每一个结点开始遍历这棵树求所能获取的最大深度,因为这是一颗无向图所以每一个结点访问过后要注意标记防止下次重复访问。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII; //分别记录树地深度和结点编号
const int N = 1e4 + 10;
int fa[N];
vector<PII> v;
int h[N], ne[N * 2], e[N * 2];
bool vis[N];
int n, idx = 0;
int find(int x) {
if (x != fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void DFS(int root, int cnt, int& maxdeep) {
maxdeep = max(cnt, maxdeep);
vis[root] = true; //标记当前结点已经访问过
for (int i = h[root]; i != -1; i = ne[i]) {
if (!vis[e[i]]) DFS(e[i], cnt + 1, maxdeep);
}
}
int main() {
scanf("%d", &n);
memset(h, -1, sizeof(h));
for (int i = 1; i <= n; i++) fa[i] = i;
int cnt = 0;
for (int i = 0; i < n - 1; i++) {
int a, b;
scanf("%d%d", &a, &b);
add(a, b); add(b, a);
fa[find(a)] = find(b);
}
for (int i = 1; i <= n; i++)
if (fa[i] == i) cnt++;
if (cnt != 1)
printf("Error: %d components\n", cnt);
else {
for (int i = 1; i <= n; i++) {
memset(vis,0, sizeof(vis));
int deepest = 0;
int cnt = 0;
DFS(i, cnt, deepest);
v.push_back({deepest, i});
}
int maxx = 0;
for (int i = 0; i < v.size(); i++) {
maxx = max(maxx, v[i].first);
}
for (int i = 0; i < v.size(); i++) {
if (maxx == v[i].first) printf("%d\n", v[i].second);
}
}
return 0;
}