写在前面
在学习并查集之前先了解这样一个小故事吧
在一个军营中,有很多不同的部队,一个部队中有数量不等的。但是战争总是一触即
发的。那么总司令怎么号召全员做好战队准备呢。这就得从上级一级一级往下给首长
发通知了,每个等级的首长负责通知他们的部队,这样就做到了,临危不乱。能够及
时做好战斗准备。
算法用途
- 解决集合的动态连通性问题
基本操作
- 并查集的初始化
void init() { //刚开始每个点都是一个集合
for (int i = 1; i <= n; i ++ ) p[i] = i;
}
- 查找集合节点编号
int find(int x) {
if (p[x] != x) p[x] = find(p[x]); //查找父节点编号+路径压缩
return p[x];
}
- 合并a,b集合
p[find(a)] = find(b);
- 判断a,b是否属于一个集合
if (find(a) == find(b))
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int n,m;
int p[N];
void init() {
for (int i = 1; i <= n; i ++ ) p[i] = i;
}
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main ()
{
cin>>n>>m;
init();
while(m -- ) {
char op;
int a,b;
cin>>op>>a>>b;
if (op == 'M') p[find(a)] = find(b);
else {
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
}
return 0;
}
读者可点击上述链接自行练习并查集裸题。