题目链接: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,已经懵了。