Ask your phone for directions and, in a heartbeat, it sifts millions of road segments to hand you
the quickest way there. Stream a video and the internet quietly routes your packets through
whichever pipes have room to spare. Both jobs live on the same object: a
These are the two great optimisation problems on weighted graphs, and this page teaches them as one story: put a number on every edge, then either add the numbers along a route (and minimise), or squeeze stuff through them (and maximise). We will meet Dijkstra's algorithm for the first and the beautiful max-flow min-cut theorem for the second.
Give every edge a non-negative weight (a distance or cost). The length of a route is just the sum of the weights of the edges you walk. The shortest-path problem asks: starting from one source vertex, what is the cheapest total cost to reach every other vertex — and by which route?
The trap is that the shortest path is often not the one with the fewest edges. A single long edge can cost more than a three-edge detour of small ones. So we cannot just count hops; we must add up weights and compare. The clever bit is doing this without checking every route by hand — there can be astronomically many.
Edsger Dijkstra's idea is a greedy one, and it is gorgeous. Keep a running best guess of the distance
to every vertex (the source is
Relaxation is the whole engine — one line that keeps only the best route found so far:
Keep going until every vertex is settled. The settled distances are the shortest distances, and the edges that "won" each relaxation form a shortest-path tree — a spanning tree of cheapest routes rooted at the source.
Here is a small weighted graph. We run Dijkstra from
Final distances from
Dijkstra dreamed the algorithm up in 1956 — reportedly in about twenty minutes, over coffee with his fiancée, while trying to show off the power of a new computer by finding the shortest drive between two Dutch cities. He published it in a three-page paper. Today essentially the same idea (souped up with a priority queue, and "A*", which adds a straight-line hint toward the goal) is what powers route planners, the internet's link-state routing protocols, and even the AI that finds a path across a video-game map. A twenty-minute idea now steers a billion journeys a day.
Plain Dijkstra breaks on negative edge weights. Its whole correctness rests on one
promise: once you settle the nearest vertex, no cheaper route can appear later. A negative edge shatters
that promise — a long path could suddenly get cheaper by dipping through a
If weights can be negative, use Bellman–Ford instead (it relaxes every edge repeatedly, and even detects negative cycles). And do not confuse the two problems: a shortest-path algorithm minimises a sum along one route — it is not the same machinery as the flow problem below, where the goal is to maximise throughput.
Now change what the numbers mean. Take a directed network with a source
The maximum-flow problem asks: what is the greatest total amount you can send from
Look at this network. The source can gush
A cut is any way of splitting the vertices into an
Here is the punchline, one of the jewels of combinatorial optimisation. That obvious ceiling — "flow can't exceed any cut" — is actually always tight. You can always find a flow that reaches the smallest cut exactly.
This turns a maximisation (find the biggest flow) and a minimisation (find the
cheapest wall) into two sides of one coin — proved by finding "augmenting paths" until none remain, the
Ford–Fulkerson method. It is also wonderfully practical: it certifies an answer. If you produce a flow
of value
Flow networks hide in surprising places. Want to assign