問題にチャレンジして、ユーザー同士で解答を教え合ったり、コードを公開してみよう!
グラフ上の任意の頂点から出発して、すべての辺を通るような一筆書きをすることができるようなグラフを準オイラーグラフと呼びます。また、そのような一筆書きの順番で頂点を並べたパスをオイラー路と呼びます。ただし、始点と終点が同じ頂点である必要はありません。
n 頂点 m 辺の有向グラフが与えられます。i 番目の辺は頂点 a_i から頂点 b_i に向かっています。なお、グラフは自己ループや多重辺を含む場合があります。
このグラフは準オイラーグラフになっています。そこで、このグラフのオイラー路を構築してください。
以下の方針や擬似コードも参考にしてください。
・ 方針
今見ている頂点から、「行き止まりになるまで進み続けて、通った頂点を戻りながらパスに追加していく」ということを辺がなくなるまで繰り返す。
・ 擬似コード
以下の関数を定義し、main 関数内で用いることで実装を完成させましょう。
// 隣接リスト g を用いて動的配列 path に頂点を追加していく関数
dfs(v, g, path):
while g[v] が空でない:
u = g[v] の末尾の要素
g[v] の末尾の要素を削除
dfs(u, g, path)
path に v を追加
// オイラー路を構築する関数
construct_eulerian_path(g, path):
// 出次数が入次数より 1 大きい頂点 (= 始点) を探す
start = 0
for v = 1 から n まで:
if 入次数(v) + 1 == 出次数(v):
start = v
break
// オイラー路を構築する
動的配列 path を空で初期化
dfs(start, g, path)
path を逆順にする // 頂点が逆順に追加されるので元に戻す
return path
n m
a_1 b_1
a_2 b_2
...
a_m b_m
オイラー路に含まれる頂点の番号を、順番に改行区切りで出力してください。
問題の条件を満たしていれば、どのような順番で頂点を出力しても正解となります。
また、末尾に改行を入れ、余計な文字を含んではいけません。
すべてのテストケースにおいて、以下の条件をみたします。
・ 入力はすべて整数
・ 2 ≦ n ≦ 100,000 = 10^5
・ 1 ≦ m ≦ 100,000 = 10^5
・ 1 ≦ a_i, b_i ≦ n (1 ≦ i ≦ m)
4 5
1 2
3 1
2 3
4 2
3 4
3
1
2
3
4
2