//得先加集合个数再合并!!!!!!!!!
核心代码:
int find(int x){//返回父节点if(x != p[x]) {p[x] = find(p[x]);//路径压缩 } //孩子不等于爸爸,就找爸爸的爸爸 return p[x];
}
题目链接:836 合并集合
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>using namespace std;int n,m;
int p[100010];void init(){for(int i=1;i<=100010;i++){p[i] = i;}
}
int find(int x){//返回父节点if(x != p[x]) {p[x] = find(p[x]);//路径压缩 } //孩子不等于爸爸,就找爸爸的爸爸 return p[x];
}int main()
{init();scanf("%d%d",&n,&m);//for(int i=1;i<=n;i++){// p[i] = i;//}while(m--){char op[2];int a,b;scanf("%s%d%d",&op,&a,&b);if(op[0] == 'M'){p[find(a)] = find(b);// int f1 = find(a);// int f2 = find(b);// printf("ffff%d %d\n",f1,f2);// if(f1 == f2) continue;// else{// p[f1] = f2;// } }else{if(find(a) == find(b))printf("Yes\n");else{printf("No\n");}}}return 0;
}
题目链接:837. 连通块中点的数量
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>using namespace std;int n,m;
int p[100010];
int size1[100010];//连通块里的个数,只保证根节点的size有意义 int find(int x){//返回父节点if(x != p[x]) {p[x] = find(p[x]);//路径压缩 } //孩子不等于爸爸,就找爸爸的爸爸 return p[x];
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){p[i] = i;size1[i] = 1;}getchar();while(m--){char op[5];int a,b;scanf("%s",&op);if(op[0] == 'C'){scanf("%d%d",&a,&b); if(find(a) == find(b)) continue;//得先加集合个数再合并!!!!!!!!! size1[find(b)] += size1[find(a)];p[find(a)] = find(b);}else if(op[1] == '1'){scanf("%d%d",&a,&b); if(find(a) == find(b))printf("Yes\n");else{printf("No\n");} }else{//求连通块的数量,先找父节点scanf("%d",&a);printf("%d\n",size1[find(a)]); }}return 0;
}