1. 4 サイクル -> true
  2. 三角形 -> false
  3. 辺なし -> true
  4. 鎖 -> true
  5. 5 サイクル -> false
  6. 完全 2 部 K2,3 -> true
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
2 部グラフ判定

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

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な 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分

2 部グラフ判定

仲の悪い 2 人を、どうしても同じ班に入れてしまう

「この 2 人は別の班にしてください」という要望が何組か来ていて、班は 2 つしかありません。全部の要望を満たす分け方はあるでしょうか。あるなら分けたいですし、無いなら早く諦めて別の方法を考えたい。

要望を線で結んだ図が、そのままグラフです。線でつながった 2 人は必ず違う班へ。この条件で 2 つに分けられるグラフを 2 部グラフと呼びます。ユーザーと商品、学生と科目、ホームとアウェイのように、性質の違う 2 種類が向かい合う関係はたいていこの形をしています。

総当たりで班を割り振ると、40 人で 2 の 40 乗通りになります。実際にはそんなに試す必要はありません。1 人の班を決めた瞬間、その人と線でつながっている全員の班が自動的に決まるからです。

決まった人から、隣を反対に塗る

手順は単純です。まだ班の決まっていない人を 1 人選んで 0 番の班に入れます。その人の隣は全員 1 番の班。その隣は全員 0 番の班。こうして交互に塗り広げていきます。

反対の班は引き算 1 つで書けます。

Python

group = {} group["山田"] = 0 for other in graph["山田"]: group[other] = 1 - group["山田"] # 0 なら 1、1 なら 0

塗り広げる途中で、すでに班の決まっている相手に出会います。そのとき見るのは 1 つだけです。相手の班が自分と 同じ なら、その時点で分けられません。違うなら、何もせず次へ進みます。この 2 つを枝分かれとして書き分けないと、すでに塗られた相手を上書きしてしまい、矛盾を見つける機会を失います。

三角形で試すと分かります。A を 0 番に、B を 1 番に、C は B の隣なので 0 番。ところが C は A ともつながっていて、A も 0 番です。ここで矛盾します。人数が奇数の輪があると、必ずこの形で行き詰まります。逆に 4 人の輪なら 0、1、0、1 と一周してぴったり閉じます。

全員を起点として一度ずつ見る

線でつながっていない人が別のところにいると、1 人から塗り広げただけでは全員に色が付きません。塗り残しがあるまま真を返すと、離れた場所にある三角形を見逃します。

外側で全員を順に見て、まだ色が付いていない人がいたら、そこから塗り直す。塊の数を数えたときと同じ形です。塊がいくつあっても、全体で 1 回ぶんの探索で片が付きます。

塗り分けの向きはどちらでもかまいません。ある塊の全員の班をそっくり入れ替えても、線でつながった 2 人が違う班であることは変わらないからです。ですから最初の 1 人を 0 番にするか 1 番にするかで悩む必要はありません。

なお、塗り分けはキューでもスタックでも書けます。色は隣との関係だけで決まるので、どの順に塗り広げても結果は同じです。

線が 1 本も無いときは、全員を片方に入れれば成立します。片方の班が空でもよいのか、と迷うところですが、「線でつながった 2 人が同じ班にいない」という条件は満たしているので成立します。

やってみよう

  • 4 人の輪 (0-1-2-3-0) は分けられる。0、1、0、1 と塗って一周してみる
  • 3 人の輪 (0-1-2-0) は分けられない。手で塗って、どこで詰まるか確かめる
  • 5 人の輪も分けられない。奇数だから、という理由を自分の言葉で言えるか
  • 要望が [[0,1],[1,2],[2,3]] のような一直線なら、必ず分けられる。輪になっていないから

要件

  1. BFS または DFS で 2 色塗り分けを試みること
  2. 複数の連結成分にも対応すること (外側で全ノードをループする)
  3. 隣接ノードが同色になった瞬間に False を返すこと

入出力例

isBipartite(4, [[0,1],[1,2],[2,3],[3,0]]) → true isBipartite(3, [[0,1],[1,2],[2,0]]) → false isBipartite(5, []) → true isBipartite(4, [[0,1],[1,2],[2,3]]) → true isBipartite(5, [[0,1],[1,2],[2,3],[3,4],[4,0]]) → false isBipartite(5, [[0,2],[0,3],[0,4],[1,2],[1,3],[1,4]]) → true

ヒント

color 配列を -1 (未塗り) / 0 / 1 で管理する。反対色は 1 - color[u]

if color[v] == -1 で未塗りを塗る、elif color[v] == color[u] で衝突検出

連結成分を漏らさないよう、すべての start を順番に試す

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

関連レッスン

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

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

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

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

  • 編集距離 (レーベンシュタイン距離)

    2 つの文字列を一致させるために必要な最小編集回数を、二次元 DP で求める古典問題に挑戦します。

  • map と filter を組み合わせる

    配列に対して `map` と `filter` を組み合わせ、偶数だけを 2 倍した結果を返す関数を実装する。関数型プログラミングの基礎を学ぶ。

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

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

  • グラフノード(頂点)とエッジ(辺)で構成されるデータ構造。
  • キュー先入れ先出し(FIFO)のデータ構造
  • スタック後入れ先出し(LIFO)のデータ構造
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
main.py
学習モード
エディタを読み込んでいます

メモ

2 部グラフ判定

⌘S で保存