【Python】グラフが木の集合(フォレスト)かどうかを判定するプログラム
問題概要
辺のリストとして表されたグラフが与えられたとき、そのグラフが木の集合(フォレスト)であるかどうかを判定します。
たとえば、入力が下図のような場合、出力は True になります。

グラフがフォレストであるためには、すべての連結成分が木であり、閉路(サイクル)が一切存在しないことが必要です。そこで、深さ優先探索(DFS)を用いて各連結成分を調べます。
解法の考え方
DFSの探索中に、すでに訪問済みのノードへ再び到達した場合、閉路が存在すると判断できます。ただし、無向グラフでは直前にいた親ノードへの「逆戻り」は必ず発生するため、このケースは除外して判定します。
アルゴリズムの手順
関数
dfs()を定義します。引数は現在のノードnodeと直前のノードprevです。nodeがすでにseenに含まれている場合はFalseを返します(閉路が検出されたことを意味します)。nodeをseenに追加します。e[node]内の各隣接ノードnについて、nがprevと異なる場合にdfs(n, node)を呼び出し、その結果がFalseならFalseを返します。すべての隣接ノードの探索が完了したら
Trueを返します。
メイン処理の手順
空のマップ(隣接リスト)
eを用意します。edges内の各辺の始点uと終点vについて、e[u]の末尾にvを、e[v]の末尾にuをそれぞれ追加します。新しい集合
seenを用意します。e内の各ノードについて、まだ訪問しておらず、かつdfs(node, -1)がFalseを返す場合はFalseを返します。すべてのノードの確認が完了したら
Trueを返します。
以下の実装例を見ると、より理解が深まるでしょう。
実装例
from collections import defaultdict
class Solution:
def solve(self, edges):
e = defaultdict(list)
for t, f in edges:
e[t].append(f)
e[f].append(t)
seen = set()
def dfs(node, prev):
if node in seen:
return False
seen.add(node)
for adj in e[node]:
if adj != prev:
if not dfs(adj, node):
return False
return True
for node in e:
if node not in seen and not dfs(node, -1):
return False
return True
ob = Solution()
edges = [[0, 1], [0, 2], [4, 3]]
print(ob.solve(edges))
入力
[[0, 1], [0, 2], [4, 3]]
出力
True
補足:動作のポイント
この例では、{0, 1, 2} からなる木と {3, 4} からなる木という2つの独立した木が存在するため、グラフ全体がフォレストとなり、結果は
Trueになります。もしグラフ内に閉路が1つでも存在すれば、DFSが訪問済みノードに再到達した時点で
Falseが返されます。計算量は DFS ベースのため O(V + E)(Vは頂点数、Eは辺数)であり、効率的に判定できます。
-
Pythonで与えられたグラフが2部グラフかどうかを判定するプログラム
2部グラフとは無向グラフが与えられたとき、そのグラフが2部グラフ(バイパータイトグラフ)であるかどうかを判定する方法を解説します。2部グラフとは、グラフのすべての頂点を2つの集合 A と B に分割でき、グラフ内のすべての辺 {u, v} が必ず一方の端点 u が集合 A、もう一方の端点 v が集合 B に属するようなグラフのことです。つまり、同じ集合内の頂点同士を結ぶ辺(A-A や B-B)が一切存在しないグラフです。例として、次のようなグラフを考えてみましょう。この場合、頂点 [0, 4] を集合 A に、[1, 2, 3] を集合 B に分類できます。すべての辺は A から B、または
-
指定された文字列がキーワードであるかどうかを確認するPythonプログラム
この記事では、指定された文字列がPythonのキーワード(予約語)であるかどうかを判定する方法について解説します。問題の概要与えられた文字列が、Pythonにおけるキーワードであるかどうかを確認する必要があります。キーワードとは、言語によって特別な用途のために予約されている単語であり、変数名や関数名などの識別子として使用することはできません。例えば「if」「for」「while」「def」などはすべてキーワードです。これらの名前を変数に使おうとすると、構文エラーが発生します。解決策:keywordモジュールの活用Pythonには標準ライブラリとしてkeywordモジュールが用意されており、これ