Back to Graph Theory Series

Part 10: Shortest Paths II — Floyd-Warshall, Johnson's & A*

August 30, 2026 Wasil Zafar 22 min read

Sometimes you need every distance at once. Sometimes you need one distance, fast, and you're willing to guess intelligently. This part covers both — the elegant three-line all-pairs algorithm, and the search strategy behind every GPS and video game.

Table of Contents

  1. All-Pairs Shortest Paths
  2. Johnson's Algorithm
  3. A* Search
  4. Exercises
  5. Conclusion & Next Steps

All-Pairs Shortest Paths

Running Dijkstra or Bellman-Ford once from every vertex trivially solves all-pairs shortest paths, at a cost of $V$ times the single-source cost. Two smarter approaches exist, aimed at different graph densities.

Big Picture Shortest-Path Toolbox

First ask: “Do I need every pair, or just one target?”

Part 10 splits into two very different goals. Floyd-Warshall and Johnson's precompute distances between all pairs of vertices; A* spends its effort on one source-target query and uses extra geometric or domain knowledge to avoid exploring irrelevant regions.

Floyd-Warshall Johnson's A* ALL pairs ALL pairs ONE pair Dense graphs Simple O(V³) matrix DP Negative edges okay Sparse graphs Reweight + repeated Dijkstra Negative edges okay Goal-directed search Uses heuristic knowledge Usually non-negative costs Same shortest-path family — different question, different structure.

Floyd-Warshall (Preview)

Floyd-Warshall computes all $V^2$ pairwise distances in a single, beautifully compact $O(V^3)$ dynamic program: for each intermediate vertex $k$ in turn, check whether routing through $k$ improves the distance between every pair $(i,j)$. No priority queue, no edge sorting — just three nested loops.

$$D^{(k)}[i,j] = \min\!\left(D^{(k-1)}[i,j],\; D^{(k-1)}[i,k] + D^{(k-1)}[k,j]\right)$$

The DP State to Remember

After round $k$, $D^{(k)}[i,j]$ is the best path from $i$ to $j$ whose internal vertices are allowed to come only from the first $k$ vertices. Each round asks one binary question: “Is the best path still the old one, or is it better if we force it to pass through the newly allowed vertex $k$?”

Visual Intuition Allow one more middle vertex

Floyd-Warshall repeatedly asks: “Does going through $k$ make this pair cheaper?”

The algorithm never grows a search frontier. It improves a distance table. For every pair $(i,j)$, vertex $k$ is considered as a possible middle stop. If $i o k o j$ is cheaper than the best route known so far, the matrix entry is replaced.

One matrix update The table entry changes Old route costs 12; the newly allowed middle vertex k creates cost 7. old D[i,j] = 12 D[i,k] = 4 D[k,j] = 3 i k j newly allowed intermediate Focus on cell D[i,j] Before round k 12 After considering k min(12, 4+3) = 7

Memory hook: Floyd-Warshall = every possible middle vertex, for every ordered pair.

Key Insight

Floyd-Warshall's $O(V^3)$ beats running Dijkstra $V$ times — $O(V(V+E)\log V)$ — exactly when the graph is dense ($E$ close to $V^2$), since then $V \cdot E \log V$ dwarfs $V^3$. On sparse graphs, repeated Dijkstra (or Johnson's algorithm, next) wins instead.

Warshall's Transitive Closure

A close relative solves a simpler question: not "what is the distance," but merely "does any path exist?" Replace Floyd-Warshall's min/plus arithmetic with OR/AND on booleans, and the same three-loop structure computes the transitive closure of a relation — the reachability matrix $R$ where $R_{ij} = \text{true}$ iff $j$ is reachable from $i$. This is literally the same algorithmic skeleton solving a Boolean version of the problem, which is why the two names (Floyd's and Warshall's) are so often mentioned in the same breath.

Boolean Twin

Same three loops; different algebra

Floyd-Warshall asks whether a route through $k$ is cheaper. Warshall asks whether a route through $k$ makes $j$ reachable at all. The control flow is identical; only the operation inside the innermost loop changes.

Floyd-Warshall Warshall distance arithmetic reachability logic D[i,j] = min(old, via k) min + R[i,j] = old OR (i-k AND k-j) OR AND Same dynamic-programming skeleton; numbers become booleans.

Johnson's Algorithm

Johnson's algorithm targets sparse graphs with possibly-negative weights — exactly where Floyd-Warshall's $O(V^3)$ is wasteful and plain Dijkstra can't be used directly. The trick: add a super-source connected to every vertex with zero-weight edges, run Bellman-Ford once from it to get potentials $h(v)$, then reweight every edge as $w'(u,v) = w(u,v) + h(u) - h(v)$ — a transformation that provably makes every edge weight non-negative without changing which path is shortest. Now Dijkstra can be run safely from every vertex on the reweighted graph, and the true distances are recovered by undoing the shift.

$$w'(u,v)=w(u,v)+h(u)-h(v)$$ $$w'(P)=w(P)+h(s)-h(t)$$

Why Reweighting Does Not Change the Best Path

Along any fixed $s\to t$ path, the internal potential terms telescope: $-h(v_1)+h(v_1)$, $-h(v_2)+h(v_2)$, and so on cancel. Every $s\to t$ path therefore receives the same additive shift $h(s)-h(t)$. If path $P_1$ was cheaper than $P_2$ before reweighting, it is still cheaper afterward.

$$\text{Time: } O(VE) \text{ (one Bellman-Ford)} + O(V(V+E)\log V) \text{ (V Dijkstra runs)}$$

Visual Intuition Reweight, don't reroute

Johnson uses Bellman-Ford once to make Dijkstra legal everywhere

The potentials $h(v)$ act like a change of coordinate system for edge weights. They remove negative edges while preserving the ranking of complete paths between each source and target.

1. Add super-source 2. Bellman-Ford once 3. Reweight edges 4. Run Dijkstra from every vertex q u v 0-weight edges to all vertices potentials h(u) = -2 h(v) = -6 also detects negative cycles u v old = -3 new = -3 + (-2) - (-6) = 1 all reweighted edges are non-negative s x t fast non-negative shortest paths Bellman-Ford pays the price once; Dijkstra then handles every source efficiently.

On a sparse graph, this beats Floyd-Warshall's flat $O(V^3)$ by a wide margin — a genuinely elegant example of one algorithm (Bellman-Ford) making another (Dijkstra) applicable where it otherwise couldn't be used.

A* Search

A* answers a single-pair query faster than Dijkstra by using a heuristic $h(v)$ — an estimate of the remaining distance from $v$ to the target — to prioritize exploration toward the goal rather than expanding outward equally in every direction. It orders its priority queue by $f(v) = g(v) + h(v)$, where $g(v)$ is the actual distance-so-far (exactly Dijkstra's $d[v]$) and $h(v)$ is the heuristic guess.

$$f(v)=g(v)+h(v)$$

Interpret the Three Numbers

$g(v)$ is money already spent and therefore known exactly. $h(v)$ is an optimistic estimate of what remains. $f(v)$ is the best-looking estimated total trip cost, so A* expands the frontier vertex with the smallest $f$.

Visual Intuition Dijkstra + a compass

A* spends effort on vertices that look promising for this target

Dijkstra ranks the frontier only by distance already traveled, $g$. A* adds a goal estimate, $h$, so vertices that are slightly farther from the start can still be preferred if they appear much closer to the destination.

Dijkstra: rank by g only A*: rank by f = g + h S T No target guidance: many equal-cost directions look equally good. S T h points toward the goal A g=4, h=6 f=10 B g=6, h=2 f=8, choose C g=3, h=8 f=11 A* may choose a vertex with larger g if its estimated remaining distance h is much smaller.

Two properties determine whether A* is trustworthy: a heuristic is admissible if it never overestimates the true remaining distance ($h(v) \leq \text{true distance}(v, \text{target})$) — this alone guarantees A* finds the optimal path. A heuristic is consistent (or monotone) if $h(u) \leq w(u,v) + h(v)$ for every edge — a stronger condition that additionally guarantees A* never needs to re-expand a finalized vertex, exactly like Dijkstra. Manhattan distance (grid movement, no diagonals) and Euclidean distance (straight-line movement) are the two most common admissible heuristics for spatial pathfinding.

Heuristic Safety

Admissible means “optimistic”; consistent means “locally self-consistent”

Admissible

The heuristic may be too small, but never too large. It never tells A* the remaining trip is more expensive than it truly is, so the optimal route cannot be unfairly hidden behind an inflated estimate.

Consistent

Moving across one edge cannot make the heuristic drop by more than that edge costs. This is the heuristic version of the triangle inequality and makes $f$ values behave monotonically along a search path.

Decision Guide

Which Part 10 tool should you reach for?

What result do you actually need? All-pairs distances One source to one target Dense graph Use Floyd-Warshall Sparse + negative edges Use Johnson's Useful heuristic Use A*

Exercises

  1. Explain, using the reweighting formula, why $w'(u,v) = w(u,v) + h(u) - h(v)$ leaves the shortest path between any fixed pair of vertices unchanged even though individual edge weights change (hint: consider what happens when you sum $w'$ along an entire path).
  2. For a small graph of your choosing, determine whether Floyd-Warshall or Johnson's algorithm would be faster in practice, based on its density.
  3. Prove that the zero heuristic $h(v) = 0$ is always both admissible and consistent, for any graph with non-negative weights.
  4. Challenge: Construct a heuristic that is admissible but not consistent, and demonstrate a case where A* using it re-expands a vertex it had already finalized.

Conclusion & Next Steps

All-pairs shortest paths (Floyd-Warshall for dense graphs, Johnson's for sparse ones with negative weights) and heuristic-guided single-pair search (A*) round out the shortest-path family entirely. Every distance question this series will ever ask reduces to one of these algorithms. Next, we leave shortest paths behind and build the theory of trees from the ground up.

Next in the Series

In Part 11: Trees & Minimum Spanning Trees, we formalize tree theory, meet the Matrix-Tree theorem, and put Kruskal's and Prim's algorithms in their full theoretical context.