- yuxitong's blog
并查集
- @ 2025-10-23 19:02:19
//顶级垃圾程序
//A very bad program
#include <bits/stdc++.h>
using namespace std;
int n, m, z, x, y; //元素个数,操作个数
//z表示操作类型,2合并1查询
struct ufs{
int parent; //表示自己的父亲是谁
int cnt; //表示自己的节点数量,秩
int value; //值
}a[20005];
int Find1(int x){ //递归的查找,简如单
return ((a[x].parent == x) ? x : a[x].parent = Find1(a[x].parent));
}
int Find2(int x){ //不递归查找,好一点
int y = x;
while (a[y].parent != y){
y = a[y].parent;
}
while (x != y){// 路径压缩,即把途中经过的结点的父亲全部改成y。
int temp = a[x].parent;
a[x].parent = y;
x = temp;
}
return y;
}
void Union(int x, int y){ //合并
x = Find2(x), y = Find2(y); //找到自己的爸爸
if (x == y){ //如果是同一个爸爸
return; //不用合并了
}
if (a[x].cnt < a[y].cnt) swap(x, y);
a[x].parent = y;
a[y].cnt += a[x].cnt;
}
bool connection(int x, int y){ //查询是否在同一集合
return (Find1(x) == Find1(y));
}
void Init(int n){ //初始化,n是元素个数
for (int i = 1; i <= n; i++){
a[i].parent = i;
a[i].cnt = 1;
a[i].value = 0;
}
}
int main(){
cin >> n >> m;
Init(n);
while (m--){
cin >> z >> x >> y;
if (z == 1){
Union(x, y);
}else{
cout << connection(x, y) << endl;
}
}
return 0;
}
INPUT:
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
OUTPUT:
0
1
0
1