Shortest Path Faster Algorithm (SPFA)
概要
単一始点最短経路問題(SSSP)を解くアルゴリズム。
重み付きグラフ \(G = (V, E)\) の始点 \(v_s\) から各頂点 \(v_t\) への最短距離を求める。
辺のコストに負が含まれていても正しく動き、負閉路も検出することができる。
ベルマンフォード法よりも高速に動作することが期待できる。
計算量
\(O(|V||E|)\)
実装
Small Label First を用いた実装
from collections import deque
INF = 10**18
# 返り値:
# None (負閉路が存在した場合)
# List[int] (それ以外)
def SPFA(N, G, s):
dist = [INF] * N
cont = [0] * N
cnts = [0]* N
dist[s] = 0
cont[s] = 1
cnts[s] += 1
que = deque([s])
while que:
v = que.popleft()
cont[v] = 0
d = dist[v]
for w, c in G[v]:
if d + c < dist[w]:
dist[w] = c + d
if not cont[w]:
cnts[w] += 1
if N <= cnts[w]:
return None
if que and c + d < que[0]:
que.appendleft(w)
else:
que.append(w)
cont[w] = 1
return dist
Verified
-
AOJ: "GRL_1_B: Shortest Path - Single Source Shortest Path (Negative Edges)": source (Python3, 0.03sec)