并查集
并查集
1)概念:处理不相交集合合并及查询问题的树型数据结构
2)基本功能:查找(find),合并(union)
3)代码实现:
#include<iostream>
using namespace std;
//并查集优化:扁平化(路径压缩),小挂大
const int MAXN = 1000005;
int father[MAXN];
int sizeOfu[MAXN];
int st[MAXN];
int find(int i){
int k = 0;
while(i!=father[i]){
st[k++] = i;
i = father[i];
}
while(k > 0){
father[st[--k]] = i;
}
return i;
}
bool isSameUnion(int a,int b){
return find(a) == find(b);
}
void Union(int a,int b){
int fa = find(a);
int fb = find(b);
if(fa != fb){
if(sizeOfu[fa] >= sizeOfu[fb]){
sizeOfu[fa] += sizeOfu[fb];
father[fb] = fa;
}
else {
sizeOfu[fb] += sizeOfu[fa];
father[fa] = fb;
}
}
}
int main(){
int n,m;
cin >> n >> m;
for(int i = 1;i<=n;i++){
father[i] = i;
sizeOfu[i] = 1;
}
while(m--){
int opt;
cin >> opt;
int n1,n2;
cin >> n1 >> n2;
if(opt == 1){
if(isSameUnion(n1,n2)){
cout << "Yes" << endl;
}
else{
cout << "No" << endl;
}
}
if(opt == 2){
Union(n1,n2);
}
}
return 0;
}
更简洁的写法如下:
#include<iostream>
using namespace std;
const int MAXN = 200005;
int father[MAXN];
int find(int i){
if(father[i] != i){
//扁平化
father[i] = find(father[i]);
}
return father[i];
}
bool isSame(int a,int b){
return find(a) == find(b);
}
void Union(int a,int b){
father[find(a)] = find(b);
}
int main(){
int n,m;
cin >> n >> m;
for(int i = 0;i<=n;i++){
father[i] = i;
}
while(m--){
int opt;
int n1,n2;
cin >> opt >> n1 >> n2;
if(opt == 1){
Union(n1,n2);
}
else if(opt == 2){
if(isSame(n1,n2)){
cout << "Y" << endl;
}
else {
cout << "N" << endl;
}
}
}
return 0;
}
浙公网安备 33010602011771号