并查集是一种数据结构,用于处理一些不相交集合(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是阿克曼函数的反函数,近似于常数。

并查集c++-实现

原文地址: http://www.cveoy.top/t/topic/rF9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录