1. paizaラーニングトップ
  2. レベルアップ問題集
  3. Union-Find・クラスカル法メニュー(言語選択)
  4. 問題一覧 PHP編
  5. ユニオン PHP編

Union-Find・クラスカル法メニューのサムネイル
ユニオン PHP編(paizaランク B 相当)

問題にチャレンジして、ユーザー同士で解答を教え合ったり、コードを公開してみよう!

問題

下記の問題をプログラミングしてみよう!

この問題ではユニオンファインド木における「ユニオン」をやってみましょう。

長さ n の数列 A を考え、数列 A の初期値を [0, 1, ..., n-1] とします。A の i 番目 (0 ≦ i ≦ n-1) の要素 A_i は整数 i の親を表しています。

ここで、ある整数 p の親を順々にたどっていった、p の祖先(または p 自身)である q について、A の q 番目の要素が q であるとき「 p は q の根である」と定義します。つまり、A の初期値では、すべての i (0 ≦ i ≦ n-1) において、i 自身が根となっています。

整数の組 (a,b) が合計 q 組与えられます。(a_j, b_j) (1 ≦ j ≦ q) に対して a_j の根を root(a_j)、b_j の根を root(b_j) として、次の操作を与えられた順番に処理し、最後に処理がすべて終了したあとの数列 A を出力してください。

root(a_j) と root(b_j) が同じでないなら、root(b_j) の親を root(a_j) とする。
同じならば何もしない。


ただし、p の根 root(p) は、p を入力として root(p) を返す次の関数 find を用いて求めてください。(この関数で求めない場合、処理終了後の数列 A が正しく出力されない可能性があります。)
def find(p)
if p == A_p then
return p
else
return find(A_p)
end if

A_p は数列 A の p 番目の要素です。

ユニオンファインド木では同じ根を持つ要素たちを同じグループとみなして管理します。上の操作のように、別の根を持つ、別のグループの要素たちの根を同じにして同一グループとする操作を一般的にユニオンと言います。

入力される値

n q
a_1 b_1
...
a_q b_q

・ 1 行目に、整数 n と整数 q が半角スペース区切りで与えられます。
・ 1 + j 行目 (1 ≦ j ≦ q) に、整数の組 a_j と b_j が半角スペース区切りで与えられます。


入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。 標準入力からの値取得方法はこちらをご確認ください
期待する出力

数列 A の i (0 ≦ i ≦ n-1) 番目の要素が i 行目となるように、合計 n 行出力してください。
末尾に改行を入れ、余計な文字、空行を含んではいけません。

条件

すべてのテストケースにおいて、以下の条件をみたします。

・ 入力はすべて整数
・ 1 ≦ n ≦ 10,000
・ 1 ≦ q ≦ n
・ 0 ≦ a_j, b_j ≦ n-1 (1 ≦ j ≦ q)
・ a_j ≠ b_j (1 ≦ j ≦ q)

入力例1

6 5
4 5
3 4
2 3
1 2
0 5

出力例1

0
0
1
2
3
4

入力例2

10 8
8 9
6 8
2 6
5 7
4 5
1 4
2 9
1 7

出力例2

0
1
2
3
1
4
2
5
6
8

問題一覧へ戻る

ページの先頭へ戻る