木における最短経路探索 - BFS解説

アルゴリズム概要

木構造において2つの頂点間の最短経路を求める問題です。木は閉路がないため、任意の2頂点間には唯一の経路が存在します。BFS(幅優先探索)を使用して効率的に経路を探索します。

時間計算量
O(n) - 全頂点を最大1回訪問
空間計算量
O(n) - グラフ表現とキューに必要
特徴
木構造では常に最短経路が一意に決まる

実装コード

from typing import List, Dict
from collections import defaultdict, deque
import sys

class Solution:
    def shortest_path_in_tree(self, n: int, x: int, y: int, edges: List[List[int]]) -> List[int]:
        """
        木における2頂点間の最短経路を BFS で求める
        """
        if not (1 <= n <= 100000):
            raise ValueError("Invalid number of nodes")
        if not (1 <= x <= n and 1 <= y <= n and x != y):
            raise ValueError("Invalid start or end node")
        if len(edges) != n - 1:
            raise ValueError("Edges must contain exactly n-1 items")

        graph: Dict[int, List[int]] = defaultdict(list)
        for a, b in edges:
            graph[a].append(b)
            graph[b].append(a)

        parent = [-1] * (n + 1)
        parent[x] = 0
        q = deque([x])

        while q:
            cur = q.popleft()
            if cur == y:
                break
            for nxt in graph[cur]:
                if parent[nxt] == -1:
                    parent[nxt] = cur
                    q.append(nxt)

        path: List[int] = []
        node = y
        while node != 0:
            path.append(node)
            if node == x:
                break
            node = parent[node]
        path.reverse()
        return path

if __name__ == "__main__":
    sys.setrecursionlimit(1 << 25)
    N, X, Y = 6, 1, 6
    edges = [[1,2],[1,3],[2,4],[2,5],[3,6]]
    solver = Solution()
    print(solver.shortest_path_in_tree(N, X, Y, edges))

アルゴリズムの動作ステップ

1

入力検証

頂点数、始点・終点、辺の数が適切かチェックします。木構造では辺の数は必ずn-1個である必要があります。

2

隣接リスト構築

与えられた辺のリストから、各頂点に接続されている隣接頂点のリストを作成します。無向グラフなので双方向に追加します。

3

BFS初期化

親ノードを記録する配列とBFS用のキューを初期化します。始点から探索を開始します。

4

BFS実行

キューから頂点を取り出し、その隣接頂点を探索します。未訪問の頂点があれば親を記録してキューに追加します。

5

終点到達判定

現在の頂点が終点と一致した場合、BFSを終了します。木構造なので必ず終点に到達できます。

6

経路復元

終点から始点まで親を辿って経路を復元し、最後に反転させて始点→終点の順序にします。

インタラクティブデモ

下のボタンを使ってBFSの動作を段階的に確認できます。

1.0x
デモを開始するには「リセット」ボタンを押してください

アルゴリズムの特徴と利点

木構造の特性

木は閉路がないため、任意の2頂点間に唯一の経路が存在します。これにより探索が効率的になります。

BFSの適用

BFSは最短経路を保証し、親ノードの記録により経路復元が簡単になります。

効率性

各頂点を最大1回だけ訪問するため、時間計算量はO(n)と非常に効率的です。