注意find()函数里的路径压缩,可以极大地提高搜索时间。merge()函数里需要比较两棵树的高度,用rank数组表示,深度小的树作为深度大的树的子树。
int par[MAX]; //记录根
int rank[MAX]; //记录树的高度
//并查集初始化
void init(int n) {
for(int i = 0; i < n; i++) {
par[i] = i;
rank[i] = 0;
}
}
//找根
int find(int x) {
if(par[x] == x)
return x;
else
return par[x] = find(par[x]); //路径压缩
}
//按秩合并
void merge(int x, int y) {
x = find(x);
y = find(y);
if(x == y)
return;
if(rank[x] < rank[y])
par[x] = y;
else {
par[y] = x;
if(rank[x] == rank[y])
rank[x]++;
}
}
//判断x, y是否在同一集合内
int same(int x, int y) {
return find(x) == find(y) ? 1: 0;
}
测试代码
#include <iostream>
#define MAX 6
using namespace std;
int par[MAX];
int rank[MAX];
void init(int n) {
for(int i = 0; i < n; i++) {
par[i] = i;
rank[i] = 0;
}
}
int find(int x) {
if(par[x] == x)
return x;
else
return par[x] = find(par[x]);
}
void merge(int x, int y) {
x = find(x);
y = find(y);
if(x == y)
return;
if(rank[x] < rank[y])
par[x] = y;
else {
par[y] = x;
if(rank[x] == rank[y])
rank[x]++;
}
}
int same(int x, int y) {
return find(x) == find(y) ? 1: 0;
}
int main() {
int a, b;
init(MAX);
for(int i = 0; i < MAX; i++) {
cin>>a>>b;
merge(a, b);
}
cout<<same(1, 4);
return 0;
}