union find
find:根を求める connect:繋げる(もともと繋がってたらfalseをreturn) same:結合か判定 size:そのノードの連結要素数
class UnionFind {
public:
//@brief Union-Findのコンストラクタ
//@param n ノード数
UnionFind(int n) : PoS(n, -1) {}
//@brief 根を求める
//@param x ノード番号
//@return xの根のノード番号
int find(int x) {
if (PoS[x] < 0) {
return x;
}
return (PoS[x] = find(PoS[x]));
}
//@brief 接続かを判定する
//@param x ノード1
//@param y ノード2
bool same(int x, int y) {
return (find(x) == find(y));
}
//@brief 連結要素数を数える
//@param x ノード番号
//@return xの連結要素数
int size(int x) {
return -PoS[find(x)];
}
//@brief 集合を繋げる
//@param x ノード1
//@param y ノード2
//@return 結合が行えたか(既に結合していた:false)
bool connect(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return false;
if (-PoS[x] < -PoS[y]) {
std::swap(x, y);
}
PoS[x] += PoS[y];
PoS[y] = x;
return true;
}
private:
//@brief 親もしくは要素数(Parent or Size)
std::vector<int> PoS;
};