Loading

并查集的基本使用

并查集,也就是在集合的树形图中,查询一个数的上一层得数(找老大)以及快速查找在两个集合中都有的数。

话不多说,直接上题目和沙雕代码!


 

并查集模板题

题目描述

如题,现在有一个并查集,你需要完成合并和查询操作。

输入格式

第一行包含两个整数 N,MN,M ,表示共有 NN 个元素和 MM 个操作。

接下来 MM 行,每行包含三个整数 Z_i,X_i,Y_iZi,Xi,Yi 。

当 Z_i=1Zi=1 时,将 X_iXi 与 Y_iYi 所在的集合合并。

当 Z_i=2Zi=2 时,输出 X_iXi 与 Y_iYi 是否在同一集合内,是的输出 Y ;否则输出 N 。

输出格式

对于每一个 Z_i=2Zi=2 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。

输入输出样例

输入 #1
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
输出 #1
N
Y
N
Y

说明/提示

对于 30\%30% 的数据,N \le 10N10,M \le 20M20 。

对于 70\%70% 的数据,N \le 100N100,M \le 10^3M103 。

对于 100\%100% 的数据,1\le N \le 10^41N104,1\le M \le 2\times 10^51M2×105 。

(题目来源:洛谷 P3367,@HansBug)


原创代码(含沙雕注释)

别直接抄!先写自己的!

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int i,j,k,n,m,s,ans,f[10010],p1,p2,p3;
 4 //f[i]表示i的集合名
 5 int find(int k){
 6     //路径压缩
 7     if(f[k]==k)return k;//如果自己就是老大,返回自己 
 8     return f[k]=find(f[k]);//如果自己不是老大,查询老大是谁 
 9 }
10 int main()
11 {
12     cin>>n>>m;//输入条件(元素和操作的数量) 
13     for(i=1;i<=n;i++)
14     {
15         f[i]=i;//初始化,所有人的老大都是自己
16     } 
17     for(i=1;i<=m;i++){
18         cin>>p1>>p2>>p3;//输入操作号(p1)和参与操作的数(p2和p3) 
19         if(p1==1)//操作1:合并集合 
20             f[find(p2)]=find(p3);//p3打赢了p2,成为p2的老大 
21         else//操作2:是否在同一集合 
22             if(find(p2)==find(p3))//检查p2和p3是否是一伙的
23                 printf("Y\n");//是,输入Y 
24             else
25                 printf("N\n");//否,输出N 
26     }
27     return 0;
28 }

 


这就是并查集的基本使用方法,喜欢请支持。

posted @ 2020-08-20 10:45  张哲涵  阅读(409)  评论(0编辑  收藏  举报