文章列表

并查集

Champ2024.12.04 00:00访问量0 次阅读
并查集
Union-Set-Find

概念

并查集(Union-Find)是一种用于处理动态连通性问题的数据结构,常用于解决图的连通性问题,例如判断两个节点是否属于同一连通分量,或者动态地合并两个集合。

<center>3个不同根的集合</center>

<center>小的并入大的</center>

代码实现

#include <iostream>
#include <vector>

using namespace std;

class UnionFind {
private:
    vector<int> parent;  // 记录每个节点的父节点
    vector<int> rank;    // 记录每个集合的秩(深度)

public:
    UnionFind(int n) {
        parent.resize(n);
        rank.resize(n, 1);
        for (int i = 0; i < n; ++i) {
            parent[i] = i;  // 初始化时每个节点的父节点是自己
        }
    }

    // 查找操作,带路径压缩
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);  // 递归到当前节点的根节点为本身(路径压缩,只保留这个节点的根)
        }
        return parent[x];
    }

    // 合并操作,按秩合并
    void unite(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            if (rank[rootX] > rank[rootY]) {
                parent[rootY] = rootX;
            } else if (rank[rootX] < rank[rootY]) {
                parent[rootX] = rootY;
            } else {
                parent[rootY] = rootX;
                rank[rootX] += 1;  // 如果秩相等,增加秩
            }
        }
    }

    // 检查两个元素是否在同一集合中
    bool connected(int x, int y) {
        return find(x) == find(y);
    }
};

int main() {
    UnionFind uf(10);

    uf.unite(1, 2);
    uf.unite(2, 3);
    uf.unite(4, 5);

    cout << uf.connected(1, 3) << endl; // 输出 1(true)
    cout << uf.connected(1, 4) << endl; // 输出 0(false)

    uf.unite(3, 4);
    cout << uf.connected(1, 4) << endl; // 输出 1(true)

    return 0;
}

应用

应用于最小生成树的Kruskal算法,用于检查是否形成环。

历史留言 (0)
ICP备案号浙ICP备2026065730号-1公安备案号浙公网安备33019202003213号