PAT.1021 Deepest Root - 并查集判断连通性,dfs搜索图
题目链接
看到题干,第一眼1e4的数据,如果用邻接矩阵1e8必爆,于是改用邻接表,然后就是在存路的时候顺便用并查集判断连通性,然后就是遍历每个点用dfs判断该点的最大深度。
一开始测试点2怎么都不过,网上也查不到关于测试点2的问题,结果仔细检查之后发现是把if(getAnc(l) != getAnc(r))
写成了if(getAnc[l] != getAnc[r])
,乐了。
似乎还可以加一个度判断的条件,只有度为1(只有一个点的情况是度为0)的点才有可能是为根深度最深的点,这里就没改了。
题解
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int l,r,n,comps,maxDepth,anc[10005],vis[10005];
vector<int> neighbors[10005];
vector<int> res;
int getAnc(int a){
if(anc[a] != a) anc[a] = getAnc(anc[a]);
return anc[a];
}
int dfs(int root,int currentDepth){
vis[root] = 1;
int md = currentDepth;
for(int neighbor : neighbors[root]){
if(vis[neighbor] == 0){
int t = dfs(neighbor,currentDepth + 1);
md = max(md,t);
}
}
return md;
}
int main(){
cin>>n;
comps = n;
for(int i = 1 ; i <= n ; ++i) anc[i] = i;
for(int i = 1 ; i < n ; ++i){
scanf(" %d %d",&l,&r);
neighbors[l].push_back(r);
neighbors[r].push_back(l);
if(getAnc(l) != getAnc(r)){
anc[getAnc(r)] = getAnc(l);
comps--;
}
}
if(comps > 1){
printf("Error: %d components",comps);
}else{
for(int i = 1 ; i <= n ; ++i){
memset(vis,0,sizeof(vis));
int t = dfs(i,0);
if(t > maxDepth){
maxDepth = t;
res.clear();
res.push_back(i);
}else if(t == maxDepth){
res.push_back(i);
}
}
for(int i : res){
cout<<i<<endl;
}
}
}