并查集的基本使用
并查集,也就是在集合的树形图中,查询一个数的上一层得数(找老大)以及快速查找在两个集合中都有的数。
话不多说,直接上题目和沙雕代码!
并查集模板题
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 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 10N≤10,M \le 20M≤20 。
对于 70\%70% 的数据,N \le 100N≤100,M \le 10^3M≤103 。
对于 100\%100% 的数据,1\le N \le 10^41≤N≤104,1\le M \le 2\times 10^51≤M≤2×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 }
这就是并查集的基本使用方法,喜欢请支持。