题目描述
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 (<=10000) 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
题目解析
原来自己使用宽度搜索,然后全部迭代一遍深度,超时了;
看了_Occult_的解法,知道树的直径的证明解法,以任意一点为起点遍历找到深度最深的子叶都是最长路径的两端之一,再从找到的子叶中选一个作为起点再进行一次遍历,找到深度最深的子叶也是最长路径的两端之一,去掉重复的就OK了。
还有学习了使用并查集确定无向图的连通块。原来我是利用visit数组使用深度遍历找。
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N_max = 10000 + 10;
int map[N_max][N_max];
int father[N_max];
int deep_max;
int deep[N_max];
int N;
int find_father(int kid)
{
if (kid == father[kid])
return kid;
else
{
return father[kid] = find_father(father[kid]);
}
}
void dfs(int a,int b, vector<int>&vis)
{
if (vis[b] != 0)return;
else
{
deep[b] = deep[a] + 1;
if (deep[b] > deep_max)
{
deep_max = deep[b];
}
vis[b] = 1;
for (int i = 1; i <= N; ++i)
{
if (map[b][i] == 1)
{
dfs(b, i, vis);
}
}
}
}
int main()
{
//生成图
cin >> N;
for (int i = 1; i < N; ++i)
{
int x, y;
scanf_s("%d %d", &x, &y);
map[x][y] = map[y][x] = 1;
}
//并查集统计无向图的连通块:1.初始化为N个树,每个树的根节点为自己;2.find_father()找到根节点;
//3.合并树;4.压缩路径将所有节点直接指向根节点,可在find_father()中使用递归完成;
for (int i = 1; i <= N; ++i)
{
father[i] = i;
}
int cnt = N;
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j < i; ++j)
{
int fa_i= find_father(i), fa_j = find_father(j);
if (map[i][j] == 1 && fa_i!=fa_j)
{
--cnt;
father[fa_i] = fa_j;
}
}
}
if (cnt > 1)
{
printf_s("Error: %d components", cnt);
}
else
{
vector<int> vis(N + 1, 0);
dfs(1,1, vis);
vector<int>root;
for (int i = 1; i <= N; ++i)
{
if (deep[i] == deep_max)
{
root.push_back(i);
}
}
vector<int> vis2(N + 1, 0);
dfs(root[0],root[0], vis2);
for (int j = 1; j <= N; ++j)
{
if (deep[j] == deep_max&&find(root.begin(), root.end(), j) == root.end())
{
root.push_back(j);
}
}
sort(root.begin(), root.end());
for (int i = 0; i < root.size(); ++i)
{
printf_s("%d\n", root[i]);
}
}
system("pause");
return 0;
}