本文主要介绍解决动态连通性一类问题的一种算法,使用到了一种叫做并查集的数据结构,称为Union-Find。
给出两个节点,判断它们是否连通(如果连通,不需要给出具体的路径)
并查集的有趣解释
理解
- 开始是每个节点的代表节点都是自身
- 对于任意两个要结拜的节点,查它们所在的集合(看它的代表节点),若代表节点相同,则return,否则,将其中一个的代表节点的代表节点(它自身)设为另一个节点的代表节点
- 最后可以用来统计集合的个数
代码代码
#include<bits/stdc++.h>
using namespace std;
int unionsearch(vector<int>& pre, int son)
{
int root = son, tmp;
while (root != pre[root]){ //找代表节点
root = pre[root];
}
while (son != root){ //路径压缩
tmp = pre[son];
pre[son] = root;
son = tmp;
}
return root;
}
int main(){
int num, road, total, son1, son2, root1, root2;
while (cin >> num >> road){
total = num;
vector<int> pre(num + 1);
for (int i = 1; i <= num; i++){
pre[i] = i;
}
while (road--){
cin >> son1 >> son2;
root1 = unionsearch(pre, son1);
root2 = unionsearch(pre, son2);
if (root1 != root2){
pre[root1] = root2;
total--;
}
}
cout << total << endl;
}
return 0;
}