1. 直線 4 ノード
  2. 近道あり
  3. s == t
  4. 到達不能
  5. 三角形
  6. サイクル混じり (近道は 0-1-3-4-5)
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
BFS で最短経路の長さを求める

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

BFS で最短経路の長さを求める

着けるのは分かった。では何歩か

前のレッスンで「たどり着けるか」は答えられるようになりました。次は「何歩で着くか」です。乗り換えの回数、迷路の最短手数、SNS で何人を介してつながっているか。どれも同じ問いです。

歩数を答えるには、探索の途中で「今、起点から何歩の場所にいるか」を持ち歩く必要があります。ただし持ち歩くだけでは足りません。最初に見つけた道が最短だと言い切れる 探索でなければ、たまたま先に見つかった遠回りを答えてしまいます。

深く潜ると、遠回りを先に見つける

0-1、1-2、2-3、0-3 の 4 本の辺を考えます。0 から 3 へは、辺 1 本で行けます。

ところが深さ優先で歩くと、0 の隣として先に 1 を選んだ場合、1 から 2、2 から 3 と潜って 3 歩で到着します。最初に着いた道が 3 歩なので、そのまま答えると間違いです。正しい答えを出すには、残りの道も全部たどって一番短いものを選び直すことになります。

幅優先ならこうなりません。0 の隣は 1 と 3 の 2 つで、どちらも「1 歩の場所」としてまとめて先に処理されます。2 歩の場所へ進むのは、1 歩の場所を全部見終わったあとです。

近い場所から順に、取りこぼさず処理する。だから 最初に目的地に触れたときの歩数が、そのまま最小 になります。これは辺 1 本の重みがどれも等しいから成り立つ話です。辺に距離や料金が付くと、辺の本数が少ない道が一番安いとは限らなくなり、この理屈は使えません。

1 段ずつ進める

歩数を持ち歩く書き方は 2 通りあります。キューに「点と歩数」の組を入れるか、同じ歩数の点をひとまとまりにして 1 段ずつ進めるかです。後者は形が見えやすいので、別の題材で見てみます。2 歩以内で届く人を集める処理です。

Python

def within_two(graph, start): seen = {start} frontier = [start] for step in range(2): next_frontier = [] for person in frontier: for other in graph[person]: if other not in seen: seen.add(other) next_frontier.append(other) frontier = next_frontier return seen

frontier が「ちょうど今の歩数で届く人たち」です。ループを 1 周すると、まとめて 1 歩ぶん外へ広がります。目的地が next_frontier に入った周回の番号が、そのまま最短の歩数です。

課題では歩数の上限がないので、目的地に触れるか、広げる先が無くなるまで回します。無くなったということは、どう歩いても届かないということなので、その場合は -1 を返します。

出発点と目的地が同じなら 0 歩です。前のレッスンと同じく、探索を始める前に返してしまいます。

やってみよう

  • edges=[[0,1],[0,2],[1,3],[2,3],[3,4]] で 0 から 4 は 3 歩。0-1-3-4 でも 0-2-3-4 でも同じ長さ
  • 別の塊にある点を目的地にすると -1 になる
  • 三角形 [[0,1],[1,2],[2,0]] で 0 から 2 は 1 歩。遠回りの 2 歩に引きずられないことを確かめる

要件

  1. BFS を使うこと (DFS は最短保証なし)
  2. 到達できない場合は -1 を返すこと
  3. s == t のときは 0 を返すこと

入出力例

shortestPath(4, [[0,1],[1,2],[2,3]], 0, 3) → 3 shortestPath(5, [[0,1],[0,2],[1,3],[2,3],[3,4]], 0, 4) → 3 shortestPath(3, [], 1, 1) → 0 shortestPath(5, [[0,1],[2,3]], 0, 3) → -1 shortestPath(3, [[0,1],[1,2],[2,0]], 0, 2) → 1 shortestPath(6, [[0,1],[1,2],[2,3],[3,1],[3,4],[4,5]], 0, 5) → 4

ヒント

キューにノードと距離をペアで乗せる、または距離配列を別に持つ

v == t の判定はキューに入れる前に行うと最短到達を見逃さない

visited はキューに入れる瞬間に立てて、二重追加を防ぐ

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • トポロジカルソート

    有向非巡回グラフ (DAG) のノードを、すべての辺 u->v で u が v より前に来るように並べた配列を返す。

  • 2 部グラフ判定

    無向グラフが 2 部グラフかどうかを BFS の彩色で判定する関数を実装する。

  • ダイクストラ法 — 重み付きグラフの最短経路

    重み付きグラフでの最短経路問題を解くダイクストラ法を、概念・図・擬似コード・Python 実装・計算量・よくある誤解まで一気通貫で学ぶ。

  • 第5章まとめクイズ — グラフ

    BFS / DFS / 最短経路 / トポロジカルソート / 2 部グラフ判定について理解度を確認する 4 択クイズ。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 処理計算や代入を表す長方形
  • キュー先入れ先出し(FIFO)のデータ構造
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
main.py
学習モード
エディタを読み込んでいます

メモ

BFS で最短経路の長さを求める

⌘S で保存