题目
思路
用size[]存储每个根节点的个数
代码
//一个连通块中点的个数都存在根节点中
#include<iostream>
using namespace std;
const int N=100005;
int siz[N]; //存储连通块中的点个数
int p[N]; //存储父节点
int n,m;
int find(int x){ //寻找根节点+路径优化
if(p[x]!=x){
p[x]=find(p[x]);
}
return p[x];
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
p[i]=i;
siz[i]=1; //注意这里siz[i]的初始值都为1,而不是i
}
while (m -- ){
string op;
int x,y;
cin>>op;
if(op[0]=='C'){
cin>>x>>y;
if(find(x)==find(y)){ //如果x,y本来就连在一起了,那么就没必要往下了
continue;
}
siz[find(y)]+=siz[find(x)];//每个连通块的个数存在他的根节点中,y树的个数为y+x(x为连过来的树)
p[find(x)]=find(y); //这句话要在siz[find(y)]+=siz[find(x)]这一句后面,不然x和y根节点的值会变
}else if(op[1]=='1'){
cin>>x>>y;
if(find(x)==find(y)){ //根节点一样,说明在一个连通块里
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}else{
cin>>y;
cout<<siz[find(y)]<<endl; //直接返回当前点根节点的size[]
}
}
return 0;
}