問題
$N$ 頂点 $M$ 辺の単純無向グラフが与えられる。グラフの最大次数を $\Delta$ とする。
Vizingの定理により、このグラフの辺は必ず $\Delta+1$ 色以内で「隣接する辺(同じ頂点を共有する辺)が異なる色になるように」彩色できることが保証されている。
入力で与えられた辺の順序に従い、若い番号から順に「その辺の両端点に接続する既に彩色済みの辺が使っていない色のうち最小の色番号($1$ から $\Delta+1$)」を貪欲に割り当てていく。 割り当て候補が全て使用済み(両端点で $\Delta+1$ 色全て使用中)になった辺が現れたら、その時点で使用されている最大の色番号を出力して終了せよ。全ての辺を彩色できた場合は、使用した最大の色番号($\Delta$ または $\Delta+1$)を出力せよ。
(本問は「単純な貪欲法だとΔ+1色に収まらないことがある」ことを実際に確認し、真のVizingの定理の証明にはfan回転とKempe chain反転という非自明な操作が必要であることを体感するための問題)
入力形式
N M
u_1 v_1
:
u_M v_M
制約
入出力例
入力例1
3 3
1 2
2 3
1 3出力例1
3三角形$K_3$は各頂点次数2($\Delta=2$)だが、3辺全てが互いに隣接するため3色必要(Class 2)。
概念図:K3の辺彩色(Class 2)
ヒント(段階的開示)
ヒント1(方向性)
辺彩色は「線グラフ(line graph)の頂点彩色」と等価。線グラフを陽に作らなくても、各頂点ごとに「その頂点に接続する辺が使用中の色集合」を管理すれば十分。
ヒント2(アプローチ)
単純な貪欲法(辺を1本ずつ処理し両端点で未使用の最小色を割り当てる)は、グラフによっては $\Delta+1$ 色を超えてしまうことがある。真のVizingの定理の構成的証明(Misra-Gries)では、色が衝突した際に「fan」と呼ばれる隣接辺の列を回転させたり、2色だけを使う交互路(Kempe chain)を反転させたりして必ず $\Delta+1$ 色以内に収める。本問ではその手前段階として単純貪欲がどこまで機能するかを実測する。
ヒント3(誘導)
used_colors = [set() for _ in range(N + 1)]
max_color_used = 0
for (u, v) in edges:
c = 1
while c in used_colors[u] or c in used_colors[v]:
c += 1
if c > delta + 1:
print(max_color_used)
return
used_colors[u].add(c)
used_colors[v].add(c)
max_color_used = max(max_color_used, c)
print(max_color_used)
色番号 $c$ を $1$ から順に増やしながら両端点で未使用かどうかチェックし、$\Delta+1$ を超えた時点で貪欲の限界を報告する。
模範解答 (Python)
import sys
def main():
data = sys.stdin.buffer.read().split()
idx = 0
N = int(data[idx]); idx += 1
M = int(data[idx]); idx += 1
edges = []
degree = [0] * (N + 1)
for _ in range(M):
u = int(data[idx]); idx += 1
v = int(data[idx]); idx += 1
edges.append((u, v))
degree[u] += 1
degree[v] += 1
delta = max(degree) if N > 0 else 0
used_colors = [set() for _ in range(N + 1)]
max_color_used = 0
for (u, v) in edges:
c = 1
while c in used_colors[u] or c in used_colors[v]:
c += 1
if c > delta + 1:
print(max_color_used)
return
used_colors[u].add(c)
used_colors[v].add(c)
max_color_used = max(max_color_used, c)
print(max_color_used)
main()
Step-by-Step 解説
頂点$v$に接続する辺は互いに全て隣接しているため、必要な色数は必ず最大次数$\Delta$以上になる。
二部グラフに限れば辺彩色数はちょうど$\Delta$色(Class 1)で済むが、一般グラフでは奇閉路の存在などにより$\Delta+1$色が必要になる場合がある(例:奇数長サイクル)。
素朴な貪欲は必ずしも$\Delta+1$色に収まらない。真のMisra-Griesのアルゴリズムでは色衝突時にfan回転とKempe chain反転で必ず$\Delta+1$色以内に収める。
各頂点の次数を数え上げその最大値$\Delta$を求める。$N\le7$なので最大次数は高々6。
全辺が$\Delta+1$色以内で彩色できれば最大使用色番号を出力、途中で破綻すれば直前までの最大色番号を出力し、単純貪欲の限界を可視化する。
よくあるミス
| ミス | 原因 | 正しい書き方 |
|---|---|---|
| $\Delta$を辺数$M$から誤って推定する | 次数の計算を怠り$M$や$N$で代用してしまう | 各頂点の次数を明示的にカウントし最大値を$\Delta$とする |
| 色番号の探索上限を$\Delta$までにしてしまう | Vizingの定理の主張を誤解する | 探索は$\Delta+1$まで許容し、それを超えたら破綻とみなす |
| 頂点彩色のアルゴリズムをそのまま流用してしまう | 辺彩色は線グラフの頂点彩色であることを忘れる | 各頂点ごとに接続する辺が使用中の色集合を管理する |
| 貪欲法がΔ+1色で必ず成功すると誤解する | 定理の存在証明とアルゴリズムの構成的成功を混同する | Vizingの定理は存在を保証するのみで、真の構成にはfan回転とKempe chain反転が必要 |
| 自己ループや多重辺を考慮した実装にしてしまう | 制約を読み違える | 本問は単純グラフのみを扱う |
次のステップ
- 発展: Misra-Griesアルゴリズムの本体(fan回転 + Kempe chain反転)を実装し、$K_3$のような貪欲法が破綻するケースでも必ず$\Delta+1$色に収まることを確認せよ。
- 次回予告: 簡潔ビットベクトル(Succinct Rank/Select、Jacobsonの階層的ブロック前計算)