Graphs and paths · 29 / 53
Bellman–Ford, Floyd–Warshall and Johnson
Understand → trace → implement → justify
1 min reading · allow extra time for practiceBellman–Ford relaxes every edge for V−1 rounds. After k rounds it covers best walks with at most k edges. An improvement on roundV reveals a source-reachable negative cycle; unreachable negative cycles do not affect that source.
Floyd–Warshall is all-pairs DP with dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]). k must be outermost to preserve the permitted-intermediate-vertices invariant. Initialise diagonal0 and minimum parallel-edge costs. Negative diagonal values signal negative cycles; affected pairs have no finite optimum.
Johnson uses Bellman–Ford potentials to reweight edges nonnegatively, then runs Dijkstra from each source. Convert distances back afterward. Negative cycles must cause failure rather than fabricated finite answers.
A worked trace
A→B4,A→C5,B→C−2 has a two-edge path costing2. Negative edges are supported; negative cycles are a separate issue.
Cost and assumptions
Bellman–Ford O(VE); Floyd O(V³) time and O(V²) space. Johnson benefits sparse graphs.
Executable example
Run with Python 3. Assertions check a small example; they do not constitute a general correctness proof. Some advanced examples are explicitly small models or reference oracles, not full production implementations.
def bellman_ford(vertices, edges, source):
d = {v: float("inf") for v in vertices}; d[source] = 0
for _ in range(len(vertices)-1):
changed = False
for u,v,w in edges:
if d[u] != float("inf") and d[u]+w < d[v]:
d[v] = d[u]+w; changed = True
if not changed: break
if any(d[u] != float("inf") and d[u]+w < d[v] for u,v,w in edges):
raise ValueError("reachable negative cycle")
return d
assert bellman_ford("ABC",[("A","B",4),("A","C",5),("B","C",-2)],"A")["C"] == 2TEST YOUR UNDERSTANDING
Your turn
Does a negative edge imply no shortest path exists?
Reveal the reasoning
No. Finite minima may exist without relevant reachable negative cycles. Edges and cycles must be distinguished.
Take it further
- Write down the input contract and the invariant before changing the example.
- Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
- Derive the cost under the stated model; measure several input sizes and explain discrepancies.
Primary reading & lecture notes
Original explanations in this course; these references provide proofs and further reading. Source links may cover the broader module.
MIT 6.006 · Introduction to Algorithms ↗