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
首先求解树的个树,这个可以深搜也可以 使用并查集,我的程序中使用的是并查集,最后只需要判断所有节点的per一共有多少种结果,即为含有多少个树
判断最深节点个数:首先确定一个节点,从该节点开始遍历整棵树,获取能达到的最深的结点集合,记为集合A;然后从集合A中任意一个结点出发遍历整棵树,获取能达到的最深顶点,记为结点集合B。集合A与B的并集就是所求结果。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
#define INF 0x3f3f3f3f
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e4+10;
typedef long long ll;
int n,head[maxn],next1[maxn*2],v[maxn*2],max_ans,per[maxn];
vector<int> ans;
set<int> s;
bool used[maxn];
void Add_edge(int x,int y,int& k)
{
v[k] = y;next1[k] = head[x];head[x] = k++;
v[k] = x;next1[k] = head[y];head[y] = k++;
}
int find_f(int x)
{
return x==per[x]?x:per[x] = find_f(per[x]);
}
void Union(int x,int y)
{
x = find_f(x);
y = find_f(y);
if(x != y)
per[x] = y;
}
void Push()
{
for(int i = 0;i < ans.size();i ++)
s.insert(ans[i]);
}
int dfs(int p,int deep)
{
bool flag = false;;
for(int i = head[p];i != -1;i = next1[i]){
if(!used[v[i]])
{
flag = true;
used[v[i]] = true;
dfs(v[i],deep+1);
used[v[i]] = false;
}
}
if(!flag)
{
if(deep > max_ans)
{
max_ans = deep,ans.clear();ans.push_back(p);
}
if(deep == max_ans)
ans.push_back(p);
}
}
int main()
{
memset(head,-1,sizeof(head));
int x,y,k=0;
scanf("%d",&n);
for(int i = 1;i <= n;i ++)per[i] = i;
for(int i = 1;i < n;i ++)
{
scanf("%d%d",&x,&y);
Add_edge(x,y,k);
Union(x,y);
}
for(int i = 1;i <= n;i ++) s.insert(find_f(i));
if(s.size()!= 1)
{
printf("Error: %d components\n",s.size());
return 0;
}
s.clear();
used[1] = true;
dfs(1,1);
Push();int pos = ans[0];
ans.clear();memset(used,0,sizeof(used));used[pos] = true;
dfs(pos,1);
Push();
for(set<int>::iterator it = s.begin();it != s.end();it ++)
printf("%d\n",*it);
return 0;
}
链式前向星中的数组忘记乘以2倍了,总是各种错误,就是没有段错误,莫名其妙的显示内存超限,emmmm,改了好久好久