首页 > 其他分享 >[模板] 并查集

[模板] 并查集

时间:2022-11-27 15:22:37浏览次数:45  
标签:py int px 查集 fa 模板 rk

并查集

struct DSU {
    vector<int> fa, rk;

    explicit DSU(int n) :fa(n + 1), rk(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, rk[i] = 0;
    }

    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 (same(x, y)) return;
        int px = fa[x], py = fa[y];
        if (rk[px] > rk[py]) fa[py] = px;
        else if (rk[px] < rk[py]) fa[px] = py;
        else fa[px] = py, rk[py]++;
    }
};
///并查集(路径压缩+按秩合并),O(nα(n)),用于维护集合关系

带权并查集

template<class T>
struct DSU {
    vector<int> fa;
    vector<T> w;

    explicit DSU(int n) :fa(n + 1), w(n + 1, T::e()) {
        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] = T::e();
    }

    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, T _w) {
        if (same(x, y)) return w[x] + -w[y] == _w;
        int px = fa[x], py = fa[y];
        fa[px] = py;
        w[px] = -w[x] + _w + w[y];
        return true;
    }//注意方向,x合并到y
};
///带权并查集(路径压缩),O(nlogn),用于维护集合带权关系

struct T {
    double rate;
    static T e() { return T{ 1.0 }; }
    friend T operator+(const T &a, const T &b) { return T{ a.rate * b.rate }; }
    friend T operator-(const T &a) { return T{ 1 / a.rate }; }
    friend bool operator==(const T &a, const T &b) { return abs(a.rate - b.rate) < 1e-6; }
};
///变量封装在一个类里,需要重载加号,负号,逻辑等于号

标签:py,int,px,查集,fa,模板,rk
From: https://www.cnblogs.com/BlankYang/p/16929752.html

相关文章