DFS(深さ優先探索)による有向グラフの連結性チェック ― C++プログラム解説
グラフの連結性チェックの基本概念
グラフが連結しているかどうかを調べるには、何らかの探索アルゴリズムを用いてすべてのノードを巡回してみます。探索が完了した時点で、まだ一度も訪問されていないノードが残っていれば、そのグラフは連結ではないと判断できます。

有向グラフの場合のポイント
無向グラフと異なり、有向グラフの場合はすべてのノードを起点として探索を行う必要があります。理由は、あるエッジが外向きの辺しか持たず、内向きの辺を持たないケースが存在するためです。そのようなノードは、他のどのノードを出発点としても到達できない可能性があります。
本記事では、探索アルゴリズムとして再帰的なDFS(深さ優先探索)を採用します。
入力と出力
入力:グラフの隣接行列
| 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 |
出力:The Graph is connected.(グラフは連結しています)
アルゴリズム
traverse(u, visited)
入力:開始ノード u、および訪問済みノードを記録するための配列 visited。
出力:u から接続されているすべての頂点を巡回します。
Begin
mark u as visited
for all vertex v, if it is adjacent with u, do
if v is not visited, then
traverse(v, visited)
done
End
isConnected(graph)
入力:判定対象となるグラフ。
出力:グラフが連結であれば true、そうでなければ false。
Begin
define visited array
for all vertices u in the graph, do
make all nodes unvisited
traverse(u, visited)
if any unvisited node is still remaining, then
return false
done
return true
End
C++サンプルコード
#include<iostream>
#define NODE 5
using namespace std;
int graph[NODE][NODE] = {{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 1},
{1, 0, 0, 0, 0},
{0, 1, 0, 0, 0}};
void traverse(int u, bool visited[]) {
visited[u] = true; // 頂点uを訪問済みとしてマーク
for(int v = 0; v<NODE; v++) {
if(graph[u][v]) { // uとvが隣接している場合
if(!visited[v]) // vが未訪問なら再帰的に探索
traverse(v, visited);
}
}
}
bool isConnected() {
bool *vis = new bool[NODE];
// すべての頂点uを起点として、全ノードが訪問できるかを確認
for(int u = 0; u < NODE; u++) {
for(int i = 0; i<NODE; i++)
vis[i] = false; // 初期状態では全ノード未訪問とする
traverse(u, vis);
for(int i = 0; i<NODE; i++) {
if(!vis[i]) // 探索で訪問できなかったノードがあれば非連結
return false;
}
}
return true;
}
int main() {
if(isConnected())
cout << "The Graph is connected.";
else
cout << "The Graph is not connected.";
}
実行結果
The Graph is connected.
計算量について
この手法では、各ノードを起点にDFSを1回ずつ実行するため、時間計算量は O(V × (V + E)) となります。Vは頂点数、Eはエッジ数です。単純な隣接行列を用いた実装では、探索ごとに O(V²) の計算が発生する点にも留意してください。より大規模なグラフでは、隣接リスト表現や強連結成分分解(Kosaraju法など)を組み合わせると効率的に判定できます。
-
BFS(幅優先探索)で無向グラフの連結性を判定するC++プログラム
グラフの連結性とは グラフが連結(接続)されているかどうかを調べるには、何らかのグラフ探索アルゴリズムを使って、すべてのノードを訪問できるかどうかを確認します。探索を完了した時点で未訪問のノードが1つでも残っていれば、そのグラフは連結していないことになります。 無向グラフの場合は、任意の1つのノードを選び、そこから探索を開始します。本記事では、探索アルゴリズムとして幅優先探索(BFS:Breadth-First Search)を採用しています。 入力と出力の例 入力 − グラフの隣接行列 0110010110110110110100110 出力 − 「グラフは連結しています。」 アルゴリズム
-
有向グラフにオイラー閉路が含まれているかどうかを判定するC++プログラム
オイラー閉路(オイラー回路)とは、グラフ上のすべての辺をちょうど1回ずつ通過できる経路のことです。このとき、同じ頂点を何度通っても構いません。オイラー閉路はオイラー路(Euler Path)の特別な形であり、オイラー路の始点がそのまま終点ともつながっている場合を指します。 ある有向グラフがオイラー閉路を持つかどうかを判定するには、次の2つの条件を満たしている必要があります。 グラフが連結であること(任意の頂点から他のすべての頂点へ到達できること)。 すべての頂点において、入次数と出次数が等しいこと。 入力 − グラフの隣接行列 01000 00100 00011 10000 0010