sotanishy's competitive programming library

sotanishy's code snippets for competitive programming

View the Project on GitHub sotanishy/cp-library-cpp

:heavy_check_mark: Union Find
(data-structure/unionfind/union_find.hpp)

Description

Union find (disjoint set union, 素集合データ構造) は,素集合を管理するデータ構造である.

空間計算量: $O(n)$

Operations

Note

$\alpha(x)$ は逆アッカーマン関数である.

この実装では高速化に path compression と union by size を用いている.どちらか一方だと計算量は $O(\log n)$ になるが,両方使用することで $O(\alpha(n))$ になる.path compression の代わりに path splitting や path halving,union by size の代わりに union by rank といった実装手法もあり,どれも同じ計算量を実現する.

Reference

Required by

Verified with

Code

#pragma once
#include <algorithm>
#include <vector>

class UnionFind {
   public:
    UnionFind() = default;
    explicit UnionFind(int n) : data(n, -1) {}

    int find(int x) {
        if (data[x] < 0) return x;
        return data[x] = find(data[x]);
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (data[x] > data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
    }

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

    int size(int x) { return -data[find(x)]; }

   private:
    std::vector<int> data;
};
#line 2 "data-structure/unionfind/union_find.hpp"
#include <algorithm>
#include <vector>

class UnionFind {
   public:
    UnionFind() = default;
    explicit UnionFind(int n) : data(n, -1) {}

    int find(int x) {
        if (data[x] < 0) return x;
        return data[x] = find(data[x]);
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (data[x] > data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
    }

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

    int size(int x) { return -data[find(x)]; }

   private:
    std::vector<int> data;
};
Back to top page