連結成分の個数
Coddyの「グラフ - データ構造シリーズ #9」コースのレッスン 13/14。
連結成分とは、すべての頂点のペアの間にパスが存在する極大の頂点集合のことです。エッジ(辺)のないグラフには頂点の数と同じだけの成分があり、完全に連結されたグラフにはちょうど1つの成分があります。
これらを数えるには、すべての頂点を走査します。まだ訪問されていない頂点を見つけるたびに、それが新しい成分となります。カウンタを増やし、そこからBFSまたはDFSを行って、到達可能なすべての頂点を訪問済みとしてマークします。次の未訪問の頂点に対してこれを続けます。
このチャレンジでは、頂点リストとエッジの両方が与えられます。なぜなら、孤立した頂点(エッジがない頂点)も独自の成分としてカウントされるため、それらが存在することを知る必要があるからです。
チャレンジ
簡単2次元整数配列 adjacency と整数配列 vertices を受け取り、グラフ内の連結成分の数を返す関数 countConnectedComponents を作成してください。
グラフの構築手順:まず vertices 内のすべてのキーに対して addVertex を実行し(これにより孤立した頂点も存在するようにします)、次に adjacency 内のすべてのペアに対して addEdge を実行します。その後、すべての頂点を走査します。未訪問の頂点が見つかるたびに新しいコンポーネントとしてカウント(カウンターをインクリメント)し、そこから DFS または BFS を実行して、そのコンポーネント全体を訪問済みとしてマークします。
必ず Graph クラス(graph で提供)を使用してください。隣接関係をモデル化するために言語標準の機能(マップ、セットなど)を使用しないでください。アルゴリズムのための補助データ(訪問済みセット、スタックなど)には標準ライブラリの型を使用しても構いません。
自分で試してみよう
#include <stdio.h>
#include "solution.h"
int main() {
int n, m;
if (scanf("%d %d", &n, &m) != 2) return 0;
int vertices[MAX_VERTICES];
for (int i = 0; i < n; i++) scanf("%d", &vertices[i]);
int adjacency[1024][2];
for (int i = 0; i < m; i++) scanf("%d %d", &adjacency[i][0], &adjacency[i][1]);
printf("%d\n", countConnectedComponents(adjacency, m, vertices, n));
return 0;
}