第五章 树 3 AcWing 1498. 最深的根
原题链接
算法标签
树的遍历
思路
如何判断给定数据可以构成树, 即给定数据为一个无环连通图
无环连通图数目判断
建议使用并查集(实际上, 采用BFS, DFS也可以判断连通块的数目, 但是相对复杂)
无向图如何存储
存储双向有向图即可
如何在搜索路径时防止反向搜索(即从叶子节点搜索至父节点)
记录父节点编号(idx),若搜索至父节点, 直接结束本次循环, 进行下次循环
如何得到最深的根的节点编号
时间复杂度
O
(
n
∗
n
)
O(n*n)
O(n∗n)即
1
0
8
10^8
108
第一个
n
n
n表示节点数量,第一个n表示每次需枚举点数.
1
s
1s
1s可进行
1
0
8
10^{8}
108次运算, 时间限制
2
s
2s
2s, 可以通过
代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define ump unordered_map
#define pq priority_queue
#define rep(i, a, b) for(int i=a;i<b;++i)
#define Rep(i, a, b) for(int i=a;i>=b;--i)
using namespace std;
typedef pair<int, int> PII;
const int N = 10005;
//int t, n, m, cnt, ans;
int h[N], ne[N*2], e[N*2], p[N], idx;
void add(int a, int b){
e[idx]=b, ne[idx]=h[a], h[a]=idx++;
}
int find(int x){
if(p[x]!=x){
p[x]=find(p[x]);
}
return p[x];
}
int dfs(int u, int fa){
int d=0;
for(int i=h[u]; ~i; i=ne[i]){
if(e[i]==fa){
continue;
}else{
d=max(d, dfs(e[i], u)+1);
}
}
return d;
}
inline int rd(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put(int x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar(x%10^48);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n=rd(), k=n;
memset(h, -1, sizeof h);
rep(i, 1, n+1){
p[i]=i;
}
int nn=n-1;
while(nn--){
int a=rd(), b=rd();
if(find(a)!=find(b)){
k--;
p[find(a)]=find(b);
}
add(a, b), add(b, a);
}
if(k>1){
printf("Error: %lld components", k);
}else{
int mx=0;
vector<int> node;
rep(i, 1, n+1){
int d=dfs(i, -1);
if(d>mx){
mx=d;
node.clear();
node.push_back(i);
}else if(d==mx){
node.push_back(i);
}
}
rep(i, 0, node.size()){
printf("%lld\n", node[i]);
}
}
return 0;
}
参考文献
AcWing 1498. 最深的根(PAT甲级辅导课)y总视频讲解
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈