题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
1021 Deepest Root (25)(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 (<=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#include<iostream>
#include<stdio.h>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<algorithm>
using namespace std;
#define maxn 10001
int head[maxn],tree[maxn],dis[maxn],vis[maxn];
int num=1,start,ends,mx=0;
set<int> sett;
queue<int> que;
struct node{
int to;
int next;
}edge[maxn];
int findR(int a){
if(tree[a]==-1) return a;//如果a是根节点的话
else{
int temp=findR(tree[a]);
tree[a]=temp;
return temp;//并且有压缩的过程
}
}
void addEdge(int from,int to){
edge[num].to=to;
edge[num].next=head[from];//from表示的是从那条边开始,to是这条边到达哪个点
head[from]=num++;//前叉式链表,head表示的是从当前点出发最后插入的那条边的编号
}
void bfs(int u){
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
que.push(u);
vis[u]=1;
while(!que.empty()){
u=que.front();que.pop();
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]){
int m=dis[u]+1;
dis[v]=m;
if(m>mx){
//start=u;
sett.clear();
sett.insert(v);
mx=m;
}else if(m==mx){
sett.insert(v);
}
que.push(v);
vis[v]=1;
}
}
}
}
int main()
{
//freopen("1.txt","r",stdin);
memset(tree,-1,sizeof(tree));
memset(head,-1,sizeof(head));
int n;
cin>>n;
int f,t;
for(int i=0;i<n-1;i++){
cin>>f>>t;
addEdge(f,t);
addEdge(t,f);
int fr=findR(f);
int tr=findR(t);
if(fr!=tr) tree[fr]=tr;
}
// for(int i=1;i<=n;i++){
// cout<<head[i]<<' '<<edge[i].next<<'\n';
// }
int comp=0;
for(int i=1;i<=n;i++){
if(tree[i]==-1)comp++;
}
if(comp==1){//那么此时才进行查找树的直径
//使用bfs
bfs(1);
int labe;
//从set中任取一点进行访问一次,那么很有可能只能得到两个点,另一个相同地位的点得不到。
for(set<int>::iterator it=sett.begin();it!=sett.end();it++){
labe=*it;
bfs(*it);break;
}
for(set<int>::iterator i=sett.begin();i!=sett.end();i++){
if(*i!=labe){
bfs(*i);break;
}
}
//sett.insert(labe);
for(set<int>::iterator i=sett.begin();i!=sett.end();i++){
cout<<*i<<'\n';
}
}else{
cout<<"Error: "<<comp<<" components";
}
return 0;
}
//先这样吧,整了3h,已经懵了。

本文介绍了一种寻找图中能够形成最高树形结构的最深根节点的算法,并通过示例说明了如何处理非树形图的情况。
261

被折叠的 条评论
为什么被折叠?



