ja / en
Overview

UnionFind

2024/07/29
2 min read

Purpose

Determines which set elements belong to, and obtains the sizes of subsets and sets of subsets.

Time Complexity

O(α(n))O(\alpha(n)), where α\alpha is the inverse Ackermann function.

Usage

Declaration

UnionFind uf(要素数);

Query

Merge

uf.merge(a,b);

Merges the set that a belongs to with the set that b belongs to.

Determine if in the same set

uf.isSame(a,b);

Determines whether a and b belong to the same set.

Set Size

uf.size(a);

Returns the size of the set to which a belongs.

Set of Subsets

uf.groups();

returns vector{subset 0, subset 1, ...}.

Implementation

class UnionFind {
public:
int n;
vector<int> p;
UnionFind(int _n) : n(_n), p(_n, -1) {}
bool merge(int a, int b) {
int x = root(a), y = root(b);
if (x == y)
return false;
if (-p[x] < -p[y])
swap(x, y);
p[x] += p[y], p[y] = x;
return true;
}
bool isSame(int a, int b) {
return root(a) == root(b);
}
int root(int a) {
if (p[a] < 0)
return a;
return p[a] = root(p[a]);
}
int size(int a) {
return -p[root(a)];
}
vector<vector<int>> groups() {
vector<int> buf(n), size(n);
for (int i = 0; i < n; i++) {
buf[i] = root(i);
size[buf[i]]++;
}
vector<vector<int>> res(n);
for (int i = 0; i < n; i++)
res[i].reserve(size[i]);
for (int i = 0; i < n; i++)
res[buf[i]].push_back(i);
res.erase(remove_if(res.begin(), res.end(), [&](const vector<int> &v) { return v.empty(); }), res.end());
return res;
}
};

Verify

//TODO