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
题意:给一个无环图,问是否是一棵树,不是,则输出Error: K components;是的话就输出deepest root(定义为节点i作为根,整棵树最深)
思路:因为是树,很容易想到dfs,当然这里也可以bfs,dp;
1.首先这里使用dfs+并查集,使用并查集合并后,看是否有多个连通分量,有的话直接输出;只有一个继续dfs,n次dfs后可以得到每个节点作为根时的最大深度,最后取最大值,输出与此最大值相等所对应的节点即可。
2.bfs,先将某个点u作为根,第一次bfs向外扩展找到最远的叶节点v,将节点v作为根节点,再来一次bfs得到的应该就是树的最大深度
3.应该也可以DP来写,参考https://blog.youkuaiyun.com/feng_zhiyu/article/details/79209689
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define mem(a,n) memset(a,n,sizeof(a))
typedef long long ll;
typedef unsigned long long ull;
const ll INF=0x3f3f3f3f;
const int N = 2e5+5;
int par[N];///par[i]表示i的父节点
bool vis[N];///访问标记
int dis[N];///dis[i]表示 节点i作为deepest root时的最长路径
vector<int>g[N];///存储无向图
int dfs(int u) {
if(vis[u]) return 0;///此时的节点已经访问过了
int cnt=0;
vis[u]=1;
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(!vis[v]) {
cnt=max(cnt,dfs(v));
}
}
return cnt+1;
}
int Find(int x) { ///找根
return par[x]==x?x:(par[x]=Find(par[x]));
}
void Unite(int x,int y) {///合并压缩路径
x=Find(x),y=Find(y);
if(x!=y) {
par[x]=y;
}
}
void init(int n) {
for(int i=0; i<=n; i++) par[i]=i;
}
int main() {
int n;
cin>>n;
init(n);
for(int i=1; i<n; i++) {
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
Unite(x,y);
}
int cnt=0;
for(int i=1; i<=n; i++) {
if(i==par[i]) cnt++;
}
if(cnt>1) {
cout<<"Error: "<<cnt<<" components";
return 0;
}
for(int i=1; i<=n; i++) {
mem(vis,0);
dis[i]=dfs(i);
// cout<<dis[i]<<endl;
}
int maxDepth=-1,index=0;
for(int i=1; i<=n; i++) {
if(dis[i]>maxDepth) {
maxDepth=dis[i];
index=i;
}
}
// cout<<"maxDepth="<<maxDepth<<" index="<<index<<endl;
for(int i=1; i<=n; i++) {
if(dis[i]==dis[index]) {
// cout<<"index="<<index<<endl;
cout<<i<<endl;
}
}
return 0;
}