proconlib

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub KodamaD/proconlib

:heavy_check_mark: test/union_find.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/unionfind"
#include "../graph/union_find.cpp"
#include <iostream>

int main() {
    int N, Q;
    std::cin >> N >> Q;
    UnionFind dsu(N);
    while (Q--) {
        int t, u, v;
        std::cin >> t >> u >> v;
        if (t == 0) {
            dsu.merge(u, v);
        }
        else {
            std::cout << dsu.same(u, v) << '\n';
        }
    }
    return 0;
}
#line 1 "test/union_find.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/unionfind"
#line 2 "graph/union_find.cpp"
#include <algorithm>
#include <cassert>
#include <vector>
#line 3 "utility/rep.cpp"

class Range {
    struct Iter {
        int itr;
        constexpr Iter(const int pos) noexcept : itr(pos) {}
        constexpr void operator++() noexcept { ++itr; }
        constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; }
        constexpr int operator*() const noexcept { return itr; }
    };
    const Iter first, last;

  public:
    explicit constexpr Range(const int first, const int last) noexcept : first(first), last(std::max(first, last)) {}
    constexpr Iter begin() const noexcept { return first; }
    constexpr Iter end() const noexcept { return last; }
};

constexpr Range rep(const int l, const int r) noexcept { return Range(l, r); }
constexpr Range rep(const int n) noexcept { return Range(0, n); }
#line 6 "graph/union_find.cpp"

class UnionFind {
    int components;
    std::vector<int> data;

  public:
    explicit UnionFind(const int size = 0) : components(size), data(size, (int)-1) {}

    int size() const { return data.size(); }
    int count() const { return components; }

    int leader(const int u) {
        assert(0 <= u and u < size());
        return data[u] < 0 ? u : data[u] = leader(data[u]);
    }

    int size(const int u) {
        assert(0 <= u and u < size());
        return -data[leader(u)];
    }

    std::pair<int, bool> merge(int u, int v) {
        assert(0 <= u and u < size());
        assert(0 <= v and v < size());
        u = leader(u);
        v = leader(v);
        if (u == v) return std::make_pair(u, false);
        if (data[u] > data[v]) std::swap(u, v);
        components -= 1;
        data[u] += data[v];
        data[v] = u;
        return std::make_pair(u, true);
    }

    bool same(const int u, const int v) {
        assert(0 <= u and u < size());
        assert(0 <= v and v < size());
        return leader(u) == leader(v);
    }

    std::vector<std::vector<int>> decompose() {
        std::vector<int> buf(size()), len(size());
        for (const int i : rep(size())) len[buf[i] = leader(i)]++;
        std::vector<std::vector<int>> ret(size());
        for (const int i : rep(size())) ret[i].reserve(len[i]);
        for (const int i : rep(size())) ret[buf[i]].push_back(i);
        ret.erase(std::remove_if(ret.begin(), ret.end(), [&](const std::vector<int>& v) { return v.empty(); }),
                  ret.end());
        return ret;
    }
};
#line 3 "test/union_find.test.cpp"
#include <iostream>

int main() {
    int N, Q;
    std::cin >> N >> Q;
    UnionFind dsu(N);
    while (Q--) {
        int t, u, v;
        std::cin >> t >> u >> v;
        if (t == 0) {
            dsu.merge(u, v);
        }
        else {
            std::cout << dsu.same(u, v) << '\n';
        }
    }
    return 0;
}
Back to top page