题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
题目描述
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 (≤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-1条边,把题目想复杂了。
n-1条边的无向图来说,如果整个图集只有一个图,那么一定没有回环(开始想成有向图并使用拓扑排序判断是否回环,多此一举)。如果不止有一个图,那么输出图的个数。
关键思路:
1、判断图:并查集。find和merage的运用。使用set判断有多少个集合。如果只有一个集合,那么是生成树,否则直接输出错误,和该图集集合树。
2、使用dfs求高度:对于每一个节点进行一次深度搜索,输出他的最大高度,对于一个遍历过的节点我们进行高度的保存,防止冗余计算,增加时间复杂度。
解题代码
#include <iostream>
#include<bits/stdc++.h>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
const int MAXSIZE = 10001;
int parent[MAXSIZE];
int isVer[MAXSIZE];
int n;
struct edge{
int v;
edge * next;
};
struct teHi{
int num;
int hi;
};
edge g[MAXSIZE];
int maxHi[MAXSIZE];
int dfs(int i,int h){
edge *e = g[i].next;
int subH = h;
isVer[i] = 1;
while(e!=NULL){
if(maxHi[e->v]!=-1){
subH = max(subH,h+maxHi[e->v]);
e=e->next;
continue;
}else{
if(isVer[e->v]==0){
subH = max(subH,dfs(e->v,h+1));
}
}
e = e->next;
}
isVer[i] = 0;
return subH;
}
int findp(int i){
if(parent[i]==i){
return i;
}
return parent[i] = findp(parent[i]);
}
void merage(int i,int j){
int pi = findp(i);
int pj = findp(j);
if(pi!=pj) parent[pj] = pi;
}
bool cmp(teHi t1,teHi t2){
if(t1.hi!=t2.hi){
return t1.hi>t2.hi;
}else{
return t1.num<t2.num;
}
}
void getRe(){
//1、判断连通分量
int sum =0;
set<int>s;
rep(i,1,n+1){
int p = findp(i);
if(s.count(p)==0){
sum++;
s.insert(p);
// cout<<p<<endl;
}
}
if(sum==1){
// dfs遍历
teHi te[n+1];
rep(i,1,n+1){
te[i].num=i;
te[i].hi=dfs(i,0);
}
sort(te+1,te+n+1,cmp);
int ma = te[1].hi;
int sum = 1;
rep(i,2,n+1){
if(te[i].hi==ma) sum++;
else break;
}
rep(i,1,sum+1){
cout<<te[i].num;
if(i!=sum) cout<<endl;
}
}else{
printf("Error: %d components",sum);
}
}
void init(){
cin>>n;
rep(i,1,n+1) {parent[i] = i;
maxHi[i] = -1;
}
rep(i,0,n-1){
int u,v;
cin>>u>>v;
edge *e = new edge;
edge *e1 = new edge;
e->v = v;
e1->v = u;
e->next = g[u].next;
g[u].next = e;
e1->next = g[v].next;
g[v].next = e1;
merage(u,v);
}
}
int main()
{
init();
getRe();
// rep(i,1,n+1) cout<<parent[i]<<" ";
return 0;
}