Skip to content
Part IA Lent Term

Bellman-Ford Algorithm

Overview

Bellman-Ford solves the SSSP problem for graphs that may contain negative edge weights. The only restriction is that there be no negative-weight cycle reachable from the source (if one exists, shortest paths are undefined). The algorithm also explicitly detects negative cycles and reports failure.

Unlike Dijkstra, which selects vertices greedily, Bellman-Ford relaxes every edge V1|V|-1 times. This brute-force approach ensures distances propagate correctly along all possible simple paths.

Pseudocode

BELLMAN-FORD(G, w, s):
  for each v in G.V:
    v.d = ∞
    v.π = NIL
  s.d = 0
  for i = 1 to |G.V| - 1:
    for each edge (u, v) in G.E:          // in any order
      RELAX(u, v, w)
  // Negative cycle detection pass
  for each edge (u, v) in G.E:
    if v.d > u.d + w(u, v):
      return FALSE                         // negative cycle exists
  return TRUE

Why V1|V|-1 Iterations Suffice

A simple shortest path has at most V1|V|-1 edges (no vertex is repeated). Consider a shortest path s=v0v1vk=ts = v_0 \to v_1 \to \cdots \to v_k = t with kV1k \le |V|-1.

  • After iteration 1: edge (v0,v1)(v_0, v_1) is relaxed, so d[v1]δ(s,v1)d[v_1] \le \delta(s, v_1). (In fact d[v1]=δ(s,v1)d[v_1] = \delta(s, v_1) if no shorter alternative exists.)
  • After iteration 2: edge (v1,v2)(v_1, v_2) is relaxed, so d[v2]δ(s,v2)d[v_2] \le \delta(s, v_2).
  • After iteration kk: d[t]δ(s,t)d[t] \le \delta(s, t).

Since kV1k \le |V|-1, after V1|V|-1 iterations all vertices have d[v]=δ(s,v)d[v] = \delta(s, v). This can be formalised as dynamic programming: let d(k)[v]d^{(k)}[v] be the shortest path weight using at most kk edges. The recurrence d(k)[v]=min(d(k1)[v],min(u,v)E{d(k1)[u]+w(u,v)})d^{(k)}[v] = \min(d^{(k-1)}[v], \min_{(u,v) \in E} \{d^{(k-1)}[u] + w(u,v)\}) is exactly what the relaxation loop computes bottom-up.

Negative Cycle Detection

After V1|V|-1 passes over all edges, every d[v]d[v] should equal δ(s,v)\delta(s, v) (or \infty for unreachable vertices). If any edge can still be relaxed (i.e. v.d>u.d+w(u,v)v.d > u.d + w(u,v) for some (u,v)(u,v)), then:

  • There exists a path of length V\ge |V| whose weight decreases from the current dd values.
  • Such a path must contain at least V|V| edges, so it contains a cycle (by the pigeonhole principle).
  • Removing that cycle cannot increase path weight (or the path wouldn’t be shorter), so the cycle must have negative total weight.

Thus a relaxable edge after V1|V|-1 passes indicates a negative-weight cycle reachable from ss.

Important caveat: A negative cycle that is not reachable from ss will not be detected, because vertices in that component maintain d=d = \infty throughout and no edge from a finite-distance vertex enters the component. This does not affect the SSSP result for reachable vertices.

Worked Example (No Negative Cycle)

Bellman-Ford algorithm: edge relaxation over multiple passes with a negative-weight edge

Same graph as Dijkstra notes: V={A,B,C,D,E,F,G}V = \{A,B,C,D,E,F,G\}, source EE. Weights: EA:5E \to A:5, EF:7E \to F:7, EG:3E \to G:3, AB:1A \to B:1, AC:2A \to C:2, GF:3G \to F:3, CD:2C \to D:2.

Processing edges in the order: (E,A), (E,F), (E,G), (A,B), (A,C), (G,F), (C,D).

VertexIniti=1i=1i=2i=2i=36i=3\ldots6
E0000
A\infty5 (E)55
B\infty\infty6 (A)6
C\infty\infty7 (A)7
D\infty\infty\infty9 (C)
F\infty7 (E)6 (G)6
G\infty3 (E)33

After i=2i=2, all distances are final. Iterations 3-6 make no changes. Final check: no edge can be relaxed \to return TRUE.

Worked Example (Negative Cycle)

Modify the graph: change GFG \to F from 3 to 4-4, add edge DAD \to A with weight 7-7, add edge DCD \to C with weight 2-2. The cycle ACDAA \to C \to D \to A has weight 2+(2)+(7)=72 + (-2) + (-7) = -7 (negative).

Run Bellman-Ford. After i=1i=1, d[C]d[C] is set to 7 (via A). After i=2i=2, d[D]d[D] is set to 5 (via C), and d[A]d[A] is set to 2-2 (via D). After i=3i=3, d[C]d[C] drops further, and so on. The values keep decreasing each iteration because the negative cycle propagates smaller distances indefinitely. After the full V1|V|-1 passes, the final check finds that some edge (e.g. (D,A)(D, A)) can still be relaxed. The algorithm returns FALSE.

Early Termination and Practical Optimisations

  • If a complete pass over all edges produces no changes, all distances are final. The algorithm can terminate early. This does not improve the worst case but helps on well-behaved inputs.
  • Process edges in an order that respects topological order if the graph is a DAG (then only one pass is needed: DAG-SSSP in Θ(V+E)\Theta(V+E)).
  • Use a queue of vertices whose dd value changed in the previous pass (Shortest Path Faster Algorithm, SPFA), which often runs faster in practice though its worst case remains O(VE)O(VE).

Running Time

  • Initialisation: Θ(V)\Theta(|V|).
  • Main loop: V1|V|-1 iterations, each scanning all E|E| edges: Θ(VE)\Theta(|V| \cdot |E|).
  • Final detection pass: Θ(E)\Theta(|E|).
  • Total: Θ(VE)\Theta(|V| \cdot |E|).

For dense graphs: Θ(V3)\Theta(|V|^3). For sparse graphs: Θ(V2)\Theta(|V|^2) if E=Θ(V)|E| = \Theta(|V|).

Comparison

PropertyDijkstraBellman-Ford
Edge weightsNon-negative onlyAny real
Negative cycle detectionNoYes
Time complexityO((V+E)logV)O((V+E)\log V)Θ(VE)\Theta(VE)
Algorithm typeGreedyDynamic programming (implicit)
Practical useFaster for w0w \ge 0Necessary for negative edges

Summary

PropertyDetail
Weight constraintAny real numbers
Negative cyclesDetected on final extra pass
Why V1V-1 passesSimple shortest path has V1\le V-1 edges
TimeΘ(VE)\Theta(V \cdot E)
SpaceΘ(V)\Theta(V) beyond graph storage
Convergence checkNo changes in a pass     \implies done

Past paper questions: y2026p1q9(c,d) (undetected negative cycles, purpose of extra relaxation pass, early termination optimisation).