A Systematic Approach to Algorithms

Vijay K. Garg · The University of Texas at Austin

Chapter 8. The Shortest Path Problem

Single-source and all-pairs distances via greedy fixing, edge relaxation, and reweighting.

This page: Classical forms. View LLP forms »

This page collects the classical descriptions of the shortest-path algorithms developed in this chapter. The lattice-linear (LLP) reformulations and chapter setup live on the LLP companion page.

Dijkstra's Algorithm

For graphs with non-negative edge weights, the greedy idea works: among the vertices not yet finalised, the one with the smallest tentative distance must be at its true shortest distance. Dijkstra repeatedly extracts that vertex (using a min-heap keyed on the tentative distance), fixes it, and relaxes its outgoing edges: $d[k] := \min(d[k], d[j] + w(j, k))$. Sequential running time: $O((n + m) \log n)$ with a binary heap, $O(m + n \log n)$ with a Fibonacci heap. Correctness rests on edge non-negativity: extending any path can only make it longer, so the smallest tentative distance is final.

BellmanFord Algorithm

Removes the non-negativity restriction. BellmanFord performs $n - 1$ passes over every edge, relaxing each. After $i$ passes, $d[x]$ is the shortest-path distance among paths using at most $i$ edges; after $n - 1$ passes, all simple shortest paths have been captured. A final $n$-th pass detects negative cycles: any edge that still relaxes witnesses a negative-weight cycle reachable from the source. Sequential running time: $\Theta(nm)$.

FloydWarshall Algorithm

A clean dynamic-programming APSP algorithm. Let $d^{(k)}[i][j]$ be the shortest-path distance from $i$ to $j$ using only $\{v_1, \ldots, v_k\}$ as intermediate vertices. The recurrence $d^{(k)}[i][j] = \min(d^{(k-1)}[i][j], d^{(k-1)}[i][k] + d^{(k-1)}[k][j])$ fits in a triple loop over $k, i, j$ with $\Theta(n^3)$ total work and $\Theta(n^2)$ space (the $k$ index can be updated in-place). Negative edges are allowed, but no negative cycles.

Johnson's Algorithm

For sparse graphs, FloydWarshall's $\Theta(n^3)$ is wasteful. Johnson's algorithm combines BellmanFord and Dijkstra: first add a virtual source $s^\star$ with zero-weight edges to every vertex and run BellmanFord to compute prices $\text{price}[v] = -\text{dist}(s^\star, v)$. Reweighting each edge $(u, v)$ to $w'(u, v) = w(u, v) + \text{price}[v] - \text{price}[u]$ yields an equivalent graph (same shortest-path structure) with all non-negative weights. Now run Dijkstra from each vertex on the reweighted graph and undo the shift via $D[u, v] = \text{dist}'(u, v) + \text{price}[u] - \text{price}[v]$. Total time: $O(mn + n^2 \log n)$ — faster than $\Theta(n^3)$ when $m = o(n^2 / \log n)$.

Looking ahead

Shortest-path machinery underpins Chapter 9 (minimum spanning trees), where Prim's algorithm shares Dijkstra's "fix-the-closest-frontier-vertex" structure but uses a different relaxation rule. Johnson's reweighting reappears in network-flow chapters as the key idea behind successive-shortest-paths and primal-dual methods. The $\Delta$-stepping algorithm (covered in the book's later sections) bridges LLP-Dijkstra and LLP-BellmanFord via a tunable bucket width.