問題
頂点数 $N$、辺数 $M$ のグラフが与えられます。
頂点には $1$ から $N$ までの番号が付けられており、$i$ 番目の辺は頂点 $A_i$ と $B_i$ を双方向につないでいます。
グラフ全体が連結であるかどうかを判定して下さい。
連結とは、グラフがどの頂点間も行き来可能であることを意味します。
[制約]
🔹$ 1 \leqq N \leqq 100000 $
🔹$ 0 \leqq M \leqq min(100000, N(N-1)/2 $
🔹$ 1 \leqq A_i < B_i \leqq N $
解き方・ソースコード
深さ優先探索とは、『進めるだけ進み、行き詰ったら一歩戻る』という考えに基づいてグラフを探索していくアルゴリズムです。
深さ優先探索を使うと、次のようにしてグラフの連結判定を行うことができます。
訪問した頂点には青色の印をつけていくことにします。
🔹【手順1】最初に、全ての頂点の色を白色に塗っておく。
🔹【手順2】頂点1を訪問して青色で塗る。その後、以下の行動を繰り返す。
・隣接する白色頂点がある場合⇒現在位置に隣接する白色の頂点を1つ選び、その頂点に移動し青色で塗る。
・隣接する白色頂点がない場合⇒一歩戻る。ただし頂点1にいる場合は戻れないので行動終了。
🔹【手順3】行動が終わった時点で全頂点が青色で塗られていたら、グラフは連結となる。
深さ優先探索は、再帰関数を使って次のように実装します。
🔹ある頂点に移動するときはdfs関数を再帰呼び出しする。
🔹一歩戻るときはreturnする。
プロブラムの計算量は $ O(N+M) $ となります。
[Google Colaboratory]
1 | #-------- 入力例1 --------- |
[実行結果(入力例1)]
各頂点の判定結果 [True, True, True, True, True, True] => 全ての結果をまとめた判定 True このグラフは連結です。
[実行結果(入力例2)]
各頂点の判定結果 [True, True, True, True, True, False] => 全ての結果をまとめた判定 False このグラフは連結ではありません。
グラフが連結となっているかどうかを判定することができました。