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
题目大意:给出n个结点(1~n)之间的n条边,问是否能构成一棵树,如果不能构成则输出它有的连通分量个数,如果能构成一棵树,输出能构成最深的树的高度时,树的根结点。如果有多个,按照从小到大输出。
我发现并查集真是个好东西!
给一张图,找出以任意一个点为root,找出树高最高的树。
思路:
无向连通图 可以 构成一棵树
-
是一棵树嘛?
否,则输出有几棵树
2.用并查集测连通性
3.找到最深(高)的树的root
比如 sample 1:
以 3, 4, 5为root, 均拥有最深的树以升序方式输出
4.dfs跑最长树,省的bfs再建一回图
(1)判断是否为同一棵树(并查集)
int par[MAXN];
int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
void unite(int x, int y)
{
x = find(x);y = find(y);
if (x == y) return ;
par[x] = y;
}
(2)dfs扫遍树长
int dfs(int n)
{
flag[n] = 1;
int ans = 0;
for (int i = 0; i < graph[n].size(); ++i)
if (flag[graph[n][i]] == 0)
ans = max(dfs(graph[n][i])+1, ans);
return ans;
}
(3)建边
void init() {
cin>>N;
for (int i = 1; i <= N; ++i)
par[i] = i;
for (int i = 1; i < N; ++i) {
int x, y;
scanf("%d%d", &x, &y);
graph[x].push_back(y);
graph[y].push_back(x);
unite(x, y); // 因为x y互联,so为同一棵树
}
}
#include<iostream>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
#define MAXN 10005
int N;
vector<int> graph[MAXN];
int par[MAXN];
int flag[MAXN];
int deep[MAXN];
int cnt;
int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
void unite(int x, int y)
{
x = find(x);y = find(y);
if (x == y) return ;
par[x] = y;
}
int dfs(int n)
{
flag[n] = 1;
int ans = 0;
for (int i = 0; i < graph[n].size(); ++i)
if (flag[graph[n][i]] == 0)
ans = max(dfs(graph[n][i])+1, ans);
return ans;
}
void init() {
cin>>N;
for (int i = 1; i <= N; ++i)
par[i] = i;
for (int i = 1; i < N; ++i) {
int x, y;
scanf("%d%d", &x, &y);
graph[x].push_back(y);
graph[y].push_back(x);
unite(x, y); // 因为x y互联,so为同一棵树
}
}
bool isATree() {
int components = 0;
for (int i = 1; i <= N; ++i)
if (par[i] == i)
components ++;
if (components > 1) {
printf("Error: %d components\n", components);
return false;
}
return true;
}
void findDeepestRoots() {
int maxDeep = -1;
for (int i = 1; i <= N; ++i) {
cnt = 0;
memset(flag, 0, sizeof(flag));
deep[i] = dfs(i);
if (deep[i] > maxDeep)
maxDeep = deep[i];
}
for (int i = 1; i <= N; ++i) {
if (deep[i] == maxDeep)
printf("%d\n", i);
}
}
int main(void)
{
init();
if (!isATree())
return 0;
findDeepestRoots();
return 0;
}