sotanishy's competitive programming library

sotanishy's code snippets for competitive programming

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

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

Description

重み付き union find は,union find の操作に加えて,同じ集合に属する他の要素に対する要素の相対的な重みを管理する.

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

Operations

Verified with

Code

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

template <typename T>
class WeightedUnionFind {
   public:
    WeightedUnionFind() = default;
    explicit WeightedUnionFind(int n) : data(n, -1), ws(n) {}

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

    T weight(int x) {
        find(x);
        return ws[x];
    }

    bool unite(int x, int y, T w) {
        w += weight(x);
        w -= weight(y);
        x = find(x);
        y = find(y);
        if (x == y) return false;
        if (data[x] > data[y]) {
            std::swap(x, y);
            w = -w;
        }
        data[x] += data[y];
        data[y] = x;
        ws[y] = w;
        return true;
    }

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

    T diff(int x, int y) { return weight(y) - weight(x); }

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

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

template <typename T>
class WeightedUnionFind {
   public:
    WeightedUnionFind() = default;
    explicit WeightedUnionFind(int n) : data(n, -1), ws(n) {}

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

    T weight(int x) {
        find(x);
        return ws[x];
    }

    bool unite(int x, int y, T w) {
        w += weight(x);
        w -= weight(y);
        x = find(x);
        y = find(y);
        if (x == y) return false;
        if (data[x] > data[y]) {
            std::swap(x, y);
            w = -w;
        }
        data[x] += data[y];
        data[y] = x;
        ws[y] = w;
        return true;
    }

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

    T diff(int x, int y) { return weight(y) - weight(x); }

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

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