1021 Deepest Root (25 分)
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 (≤ 10 4 10^4 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个节点,N-1条边的图,若该图满足树结构,则输出使得树深度最大的根节点,若不满足,则输出联通域个数。
解题过程:
- 如果给出的图不满足树结构则要求输出联通域个数,所以首先应该使用dfs求出图的连通域个数,若只有一个联通域则可断定该图满足树结构,此处不用再判断图中是否含有环,因为本题只有N-1条边,如果一个图中只有一个联通域,且含有环则图中的边的个数应大于等于N。
- 如果1中判断满足树结构,则用dfs求出以每个节点为根节点时树的深度,最后输出深度最大的点的标号即可
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10004;
vector<vector<int> > G(maxn);
int mark[maxn];
int parent[maxn];
int visited[maxn];
int N;
void dfs1(int u)
{
mark[u] = 1;
for(int j = 0;j < G[u].size(); j++)
{
if(mark[G[u][j]] == 0)
dfs1(G[u][j]);
}
}
int dfs2(int u)
{
mark[u] = 1;
int ans = 1;
for(int i = 0;i < G[u].size(); i++)
{
if(mark[G[u][i]] == 0)
ans = max(ans,1+dfs2(G[u][i]));
}
return ans;
}
int getComponents()
{
memset(mark,0,sizeof(mark));
int ans = 0;
for(int i = 1;i <= N; i++)
{
if(mark[i] == 0)
{
dfs1(i);
ans++;
}
}
return ans;
}
int main(int argc, char const *argv[])
{
int u,v;
cin >> N;
for(int i = 0;i < N-1; i++)
{
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
int parts = getComponents();
if(parts != 1) //如果含有多个联通域
cout << "Error: " << parts << " components" << endl;
else
{
int depth[N+1],max_depth = -1; // 分别用于记录以i为根节点的深度 最大深度
for(int i = 1;i <= N; i++)
{
memset(mark,0,sizeof(mark));
depth[i] = dfs2(i);
if(max_depth < depth[i])
max_depth = depth[i];
}
for(int i = 1;i <= N; i++)
{
if(depth[i] == max_depth)
cout << i << endl;
}
}
return 0;
}