- 编程题
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
题目大意:
给出节点数和边,求它是不是一棵树。如果不是,求它有几个独立模块;如果是,求使这棵树高度最大的根节点。
解题思路:
先用 dfs 求一共有几个独立模块。深搜的同时记录最大高度和该高度上的所有子节点。
如果只有一个独立模块,把最大高度的所有子节点记录下来。再从这些子节点中随意选择一个子节点作为根节点,重新做一次深搜,记录最大高度的所有子节点。使用set求这两个子节点集合的并集,set自动从小到大排序输出。
注意事项:
1、刚开始采用建图的方法(e[10001][10001]),导致内存超限。改用向量数组,通过了测试点;
2、求两个子节点集合的并集时,本来是用向量数组记录,再排序,再从小到大输出不重复的项(因为也许两个集合中有相同的节点),这个方法比较麻烦。改用set,自动排除重复项,自动排序,方便许多;
3、set输出用 for(auto it = ans.begin(); it != ans.end(); it++) printf("%d\n", *it); 不能直接 ans[i] 输出。
4、book[10001]发生段错误,改成book[10002]后通过测试。。。
源代码:
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<set>
using namespace std;
const int inf = 99999999;
int n, book[10010] = { 0 }, maxlevel = 0;
vector<vector<int>>e;
vector<int>root;
set<int>ans;
bool cmp(int a, int b) { return a < b; }
void dfs(int r, int c, int level)
{
book[r] = c;
if (level > maxlevel)
{
maxlevel = level;
root.clear();
root.push_back(r);
}
else if (level == maxlevel)
root.push_back(r);
for (int j = 0; j < e[r].size(); j++)
{
if (book[e[r][j]] == 0)dfs(e[r][j], c, level + 1);
}
return;
}
int main()
{
int i, j, k, a, b, cnt;
scanf("%d", &n);
e.resize(n + 1);
for (i = 1; i < n; i++)
{
scanf("%d %d", &a, &b);
e[a].push_back(b);
e[b].push_back(a);
}
cnt = 0;
for (i = 1; i <= n; i++)
{
if (book[i] == 0)
{
cnt++;
dfs(i, cnt, 0);
}
}
if (cnt > 1)printf("Error: %d components", cnt);
else
{
for (i = 0; i < root.size(); i++)ans.insert(root[i]);
int r0 = root[0];
root.clear();
maxlevel = 0;
for (i = 1; i <= n; i++)book[i] = 0;
dfs(r0, cnt, 0);
for (i = 0; i < root.size(); i++)ans.insert(root[i]);
for (auto it=ans.begin(); it!=ans.end(); it++)
{
printf("%d\n", *it);
}
}
system("pause");
return 0;
}