概要
全点対最短経路問題(APSP)を解くアルゴリズム。
グラフ \(G = (V, E)\) の全てのペア \((v, w)\) 間の最短経路コストを求める。
Bellman-Ford Algorithmで一度負辺を除去した上で、Dijkstra’s Algorithmで各頂点からの最短経路を計算する。
計算量
二分ヒープ実装で \(O((|V| + |E|) |V| \log |V|)\)
実装
from collections import deque
from heapq import heappush, heappop
INF = 10**30
def Johnson(G, N):
h = [0]*N
update = 1
for i in range(N):
update = 0
for v in range(N):
d = h[v]
for w, c in G[v]:
if c + d < h[w]:
h[w] = d + c
update = 1
if not update:
break
else:
return None
for v in range(N):
d = h[v]
g = G[v]
for j, (w, c) in enumerate(g):
g[j] = (w, c + d - h[w])
D = []
for i in range(N):
dst = [INF]*N
dst[i] = 0
que = [(0, i)]
while que:
cost, v = heappop(que)
if dst[v] < cost:
continue
for w, c in G[v]:
if cost + c < dst[w]:
dst[w] = r = cost + c
heappush(que, (r, w))
v = h[i]
for j in range(N):
if dst[j] == INF:
dst[j] = INF
else:
dst[j] -= v - h[j]
D.append(dst)
return D
Verified
-
AOJ: "GRL_1_C: Shortest Path - All Pairs Shortest Path": source (Python3, 0.20sec)