-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathunionfind.hpp
30 lines (29 loc) · 1.05 KB
/
unionfind.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once
#include <algorithm>
#include <numeric>
#include <utility>
#include <vector>
// CUT begin
// UnionFind Tree (0-indexed), based on size of each disjoint set
struct UnionFind {
std::vector<int> par, cou;
UnionFind(int N = 0) : par(N), cou(N, 1) { iota(par.begin(), par.end(), 0); }
int find(int x) { return (par[x] == x) ? x : (par[x] = find(par[x])); }
bool unite(int x, int y) {
x = find(x), y = find(y);
if (x == y) return false;
if (cou[x] < cou[y]) std::swap(x, y);
par[y] = x, cou[x] += cou[y];
return true;
}
int count(int x) { return cou[find(x)]; }
bool same(int x, int y) { return find(x) == find(y); }
std::vector<std::vector<int>> groups() {
std::vector<std::vector<int>> ret(par.size());
for (int i = 0; i < int(par.size()); ++i) ret[find(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;
}
};