模板

struct disjoint_set {

    std::vector<int> s, sz;

    disjoint_set() = default;
    disjoint_set(size_t size) : s(size + 1, 0), sz(size + 1, 1) {
        std::iota(s.begin(), s.end(), 0); // <numeric>
    }

    int find(int x) {
        return x == s[x] ? x : s[x] = find(s[x]); // 路径压缩
    }

    bool unite(int x, int y){
        x = find(x), y = find(y);
        if(x == y) return true; // 已经联通返回 true;
        if(sz[x] > sz[y])
            std::swap(x, y);
        sz[y] += sz[x];   // 按秩合并
        s[x] = y;
        return false; 
    }
};

使用

初始化

disjoint_set s(n) 初始化 \([0, n]\) 的并查集

查找根节点

find(x)

合并

unite(x, y)

如果xy 已经联通了,得到true, 否则合并xy, 并得到false

其他

#109. 并查集

OI-wiki 并查集