DSU

無向グラフに対して、

をならし $O(\alpha(n))$ 時間で処理することが出来ます。

また、内部的に各連結成分ごとに代表となる頂点を $1$ つ持っています。辺の追加により連結成分がマージされる時、新たな代表元は元の連結成分の代表元のうちどちらかになります。

コンストラクタ

dsu d(int n)

制約

計算量

merge

int d.merge(int a, int b)

辺 $(a, b)$ を足します。

$a, b$ が連結だった場合はその代表元、非連結だった場合は新たな代表元を返します。

制約

計算量

same

bool d.same(int a, int b)

頂点 $a, b$ が連結かどうかを返します。

制約

計算量

leader

int d.leader(int a)

頂点 $a$ の属する連結成分の代表元を返します。

制約

計算量

size

int d.size(int a)

頂点 $a$ の属する連結成分のサイズを返します。

制約

計算量

groups

vector<vector<int>> d.groups()

グラフを連結成分に分け、その情報を返します。

返り値は「「一つの連結成分の頂点番号のリスト」のリスト」です。 (内側外側限らず)vector内でどの順番で頂点が格納されているかは未定義です。

計算量

使用例

AC code of https://atcoder.jp/contests/practice2/tasks/practice2_a

#include <atcoder/dsu> #include <cstdio> using namespace std; using namespace atcoder; int main() { int n, q; scanf("%d %d", &n, &q); dsu d(n); for (int i = 0; i < q; i++) { int t, u, v; scanf("%d %d %d", &t, &u, &v); if (t == 0) { d.merge(u, v); } else { if (d.same(u, v)) { printf("1\n"); } else { printf("0\n"); } } } return 0; }