[模板] 并查集

并查集

///并查集(路径压缩),修改查询O(logn),用于维护集合关系
struct DSU {
    vector<int> fa;

    explicit DSU(int n):fa(n + 1) {
        for (int i = 1;i <= n;i++)
            fa[i] = i;
    }

    void init(int n) {
        for (int i = 1;i <= n;i++)
            fa[i] = i;
    }

    int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

    bool same(int x, int y) { return find(x) == find(y); }

    void merge(int x, int y) {
        if ((x = find(x)) == (y = find(y))) return;
        fa[x] = y;
    }
};

带权并查集

///带权并查集(路径压缩),修改查询O(logn),用于维护集合带权关系
//一般都要大改find和merge,注意merge是x合并到y
struct DSU {
    vector<int> fa;
    vector<double> w;

    explicit DSU(int n):fa(n + 1), w(n + 1, 1) {
        for (int i = 1;i <= n;i++)
            fa[i] = i;
    }

    void init(int n) {
        for (int i = 1;i <= n;i++)
            fa[i] = i, w[i] = 1;
    }

    int find(int x) {
        if (fa[x] == x) return x;
        int pre = fa[x];
        fa[x] = find(fa[x]);
        w[x] = w[x] * w[pre];
        return fa[x];
    }

    bool same(int x, int y) { return find(x) == find(y); }

    bool merge(int x, int y, double _w) {
        if (same(x, y)) return abs(w[x] / w[y] - _w) < 1e-6;
        int px = fa[x], py = fa[y];
        fa[px] = py;
        w[px] = 1 / w[x] * _w * w[y];
        return true;
    }
};
posted @ 2022-11-27 15:19  空白菌  阅读(24)  评论(0编辑  收藏  举报