This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "structure/union-find/union-find.hpp"
集合を高速に扱うためのデータ構造です。集合を合併する操作(unite)と、ある要素がどの集合に属しているか(find)を問い合わせる操作を行うことができます。
UnionFind(size_t n)
n
個の集合を作成します。集合 $i(0 \leq i \lt n)$ には要素 $i$ のみが属します。
bool unite(int x, int y)
集合 x
と y
を併合します。併合済のとき false
、未併合のとき true
を返します。
int find(int k)
要素 k
が属する集合の代表元を返します。
int size(int k)
要素 k
が属する集合の要素数を返します。
bool same(int x, int y)
要素 x
と y
が同じ集合に属する場合 true
、異なる集合に属する場合は false
を返します。
vector< vector< int > > groups()
それぞれの集合に含まれる要素を列挙し、それを返します。それぞれの集合内の要素は昇順に格納されますが、集合の順番は未定義です。
#pragma once
struct UnionFind {
vector<int> data;
UnionFind() = default;
explicit UnionFind(size_t sz) : data(sz, -1) {}
bool unite(int x, int y) {
x = find(x), y = find(y);
if (x == y) return false;
if (data[x] > data[y]) swap(x, y);
data[x] += data[y];
data[y] = x;
return true;
}
int find(int k) {
if (data[k] < 0) return (k);
return data[k] = find(data[k]);
}
int size(int k) { return -data[find(k)]; }
bool same(int x, int y) { return find(x) == find(y); }
vector<vector<int> > groups() {
int n = (int)data.size();
vector<vector<int> > ret(n);
for (int i = 0; i < n; i++) {
ret[find(i)].emplace_back(i);
}
ret.erase(remove_if(begin(ret), end(ret),
[&](const vector<int> &v) { return v.empty(); }),
end(ret));
return ret;
}
};
#line 2 "structure/union-find/union-find.hpp"
struct UnionFind {
vector<int> data;
UnionFind() = default;
explicit UnionFind(size_t sz) : data(sz, -1) {}
bool unite(int x, int y) {
x = find(x), y = find(y);
if (x == y) return false;
if (data[x] > data[y]) swap(x, y);
data[x] += data[y];
data[y] = x;
return true;
}
int find(int k) {
if (data[k] < 0) return (k);
return data[k] = find(data[k]);
}
int size(int k) { return -data[find(k)]; }
bool same(int x, int y) { return find(x) == find(y); }
vector<vector<int> > groups() {
int n = (int)data.size();
vector<vector<int> > ret(n);
for (int i = 0; i < n; i++) {
ret[find(i)].emplace_back(i);
}
ret.erase(remove_if(begin(ret), end(ret),
[&](const vector<int> &v) { return v.empty(); }),
end(ret));
return ret;
}
};