并查集

1.并查集模板  P3367 【模板】并查集 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 int n,m,x,y,z;
 6 int p[N]; //p[x] 是 x 点的祖先
 7 
 8 int find(int x)  // 并查集
 9 {
10     if (p[x] != x) p[x] = find(p[x]); //父亲不是自己就继续接着找
11     return p[x]; //返回祖先
12 }
13 
14 
15 int main ()
16 {
17     cin >> n >> m;
18     for (int i = 1; i <= n; i ++ ) p[i] = i;
19     
20     while (m -- )
21     {
22         cin >> z >> x >> y;
23         int a = find(x), b = find(y);
24         
25         if(z == 1) p[a] = b;//x点的祖先的爹记为y点的祖先
26         
27         if(z == 2) 
28         {
29             if(a == b) puts("Y"); // 爹一样就说明在一个集合里
30             else puts("N"); //爹不一样说明不在一个集合里
31         }
32     }
33     
34     return 0;
35 }
View Code
复制代码

 acwing836 裸并查集模板

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 100010;
 5 int p[N]; //表示每个元素存的父节点是谁
 6 int n,m;
 7 
 8 int find(int x) //返回x的祖宗节点的编号 + 路径压缩
 9 {
10     if(p[x] != x) p[x] = find(p[x]); 
11     return p[x];
12 }
13 
14 int main()
15 {
16     scanf("%d%d", &n, &m);
17     
18     for (int i = 1; i <= n; i ++ ) p[i] = i; //初始化把每个节点的父节点赋成自己
19     
20     while (m -- )
21     {
22        char op[2];
23        int a,b;
24        scanf("%s%d%d", op, &a,&b);
25        
26        if(op[0] == 'M') p[find(a)] = find(b);
27        else 
28        {
29            if(find(a) == find(b)) puts("Yes");
30            else puts("No");
31        }
32     }
33 }
Code
复制代码

 2.连通块中 点的数量 维护并查集中一个集合的点的数量

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 100010;
 5 int p[N];//表示每个元素存的父节点是谁
 6 int siz[N]; //表示每个集合中点的数量
 7 int n,m;
 8 
 9 int find(int x) //返回x的祖宗节点的编号 + 路径压缩
10 {
11     if(p[x] != x) p[x] = find(p[x]); //如果这个点的父节点不是自己那么则向上走一层知道找到根节点等于自己,并且回溯压缩路径
12     return p[x];
13 }
14 
15 int main()
16 {
17     scanf("%d%d", &n, &m);
18     
19     for (int i = 1; i <= n; i ++ ) 
20     {
21         p[i] = i; //初始化把每个节点的父节点赋成自己
22         siz[i] = 1;
23     }
24     
25     
26     while (m -- )
27     {
28        char op[2];
29        int a,b;
30        scanf("%s", op);
31        
32        if(op[0] == 'C')
33        {
34            scanf("%d%d", &a, &b);
35            if(find(a) == find(b)) continue;
36            siz[find(b)] += siz[find(a)];
37            p[find(a)] = find(b); //连接其实就是集合的合并
38        }
39        
40        else if(op[1] == '1') //查询是否在同一个集合里面
41        {
42            scanf("%d%d", &a, &b);
43            if(find(a) == find(b)) puts("Yes");
44            else puts("No");
45        }
46        else 
47        {
48            scanf("%d", &a);
49            printf("%d\n",siz[find(a)]);
50        }
51     }
52 }
View Code
复制代码

 

posted @   rw156  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示