并查集c++-实现
并查集是一种数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。它支持两个操作:合并(Union)和查找(Find)。并查集可以高效地解决连通性问题,例如判断图中是否存在环。
在C++中,可以使用以下代码实现并查集:
#include <iostream>
#include <vector>
using namespace std;
class UnionFind {
public:
vector<int> parent;
vector<int> rank;
UnionFind(int n) {
parent.resize(n);
rank.resize(n);
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 0;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
void unionSet(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}
if (rank[rootX] < rank[rootY]) {
swap(rootX, rootY);
}
parent[rootY] = rootX;
if (rank[rootX] == rank[rootY]) {
rank[rootX]++;
}
}
};
int main() {
UnionFind uf(10);
uf.unionSet(0, 1);
uf.unionSet(2, 3);
uf.unionSet(4, 5);
uf.unionSet(6, 7);
uf.unionSet(0, 2);
uf.unionSet(6, 4);
uf.unionSet(0, 6);
cout << uf.find(0) << endl; // 输出6
cout << uf.find(3) << endl; // 输出3
return 0;
}
在上面的代码中,我们使用了两个vector,parent存储每个节点的祖先节点(代表该节点所在集合的根节点),rank存储每个节点所在集合的秩,即集合的高度。
在并查集的初始化中,每个节点的祖先节点都是它本身。在查找时,如果节点的祖先节点不是它本身,就递归地查找它的祖先节点。在合并时,首先找到两个节点所在集合的根节点,如果它们已经在同一个集合中,则不需要合并;否则,将其中秩较小的集合合并到秩较大的集合中,同时更新祖先节点和秩。这里使用了路径压缩和按秩合并两种优化,可以使并查集的时间复杂度为O(alpha(n)),其中alpha是阿克曼函数的反函数,近似于常数。
原文地址: http://www.cveoy.top/t/topic/rF9 著作权归作者所有。请勿转载和采集!