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
Code:
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;
const int MAXN = 10005;
vector<vector<int>> road;
vector<int> temp;
set<int> result;
bool visited[MAXN];
int N = 0, max_length = 0;
void dfs(int nd, int len)
{
if (len > max_length)
{
temp.clear();
temp.push_back(nd);
max_length = len;
}
else if (len == max_length)
temp.push_back(nd);
visited[nd] = 1;
for (int i = 0; i < road[nd].size(); i++)
if (!visited[road[nd][i]])
dfs(road[nd][i], len + 1);
}
int main()
{
scanf("%d", &N);
road.resize(N + 1);
memset(visited, 0, sizeof(visited));
for (int i = 0; i < N - 1; i++)
{
int a, b;
scanf("%d%d", &a, &b);
road[a].push_back(b);
road[b].push_back(a);
}
int cnt = 0; int s0 = 0;
for (int i = 1; i <= N; i++)
{
if (!visited[i])
{
dfs(i, 1);
if (i == 1)
{
if (temp.size() != 0) s0 = temp[0];
for (int j = 0; j < temp.size(); j++)
result.insert(temp[j]);
}
cnt++;
}
}
if (cnt > 1)
printf("Error: %d components\n", cnt);
else
{
temp.clear();
memset(visited, 0, sizeof(visited));
max_length = 0;
dfs(s0, 1);
for (int i = 0; i < temp.size(); i++)
result.insert(temp[i]);
for (auto it : result)
printf("%d\n", it);
}
return 0;
}
思路
首先这道题要用邻接表,不能用邻接矩阵,不然会爆内存,然后算法的思路是,先找连通分量,找到过程中,找到有最深深度的根,然后如果连通分量为1,那么再从这个有最深深度的根开始dfs,就能找到所有有最深深度的根,如果连通分量不为1,就输出Error。
为什么要找到有最深深度的根,因为如果你从3开始dfs,会出错,正确的应该是从5开始dfs。