PTA甲级1118,压缩路径的并查集算法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int leader[10005];
vector<int> trees;
int findleader(int bird){
int temp=bird;
//寻找最终leader
while(bird!=leader[bird])
bird=leader[bird];
//压缩路径
while(temp!=leader[temp]){
int t_temp = temp;
temp = leader[temp];
leader[t_temp] = bird;
}
return bird;
}
int main(){
int n,q,num=0,tree=0; cin>>n;
for(int i=0;i<10005;i++)
leader[i]=i;
for(int i=0;i<n;i++){
int k,lead; cin>>k>>lead;
num=max(num,lead);
leader[lead]=findleader(lead);
for(int j=1;j<k;j++){
int curr; cin>>curr;
num=max(num,curr);
//合并集合(仅将组Blead的leader[lead]改为组A的lead)
leader[findleader(curr)]=findleader(lead);
}
}
//将组B所有成员的leader改为组A的lead
for(int i=1;i<=num;i++)
findleader(i);
for(int i=1;i<=num;i++)
if(find(trees.begin(),trees.end(),leader[i])==trees.end()){
trees.push_back(leader[i]);
tree++;
}
cout<<tree<<" "<<num<<endl;
cin>>q;
for(int i=0;i<q;i++){
int b1,b2; cin>>b1>>b2;
if(leader[b1]==leader[b2]) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}