Choosing an Algorithm from the Problem
A shortest-path problem is specified not just by a graph, but also by what is being asked: one source to all reachable vertices, one source to a particular target, or distances between every pair. The edge weights and the graph’s structure matter too. Dijkstra’s algorithm applies when all edge weights are nonnegative; topological-order relaxation applies to directed acyclic graphs, even if some weights are negative; Bellman–Ford handles negative weights and detects reachable negative cycles; and Floyd–Warshall computes all-pairs distances.
All graphs below are finite weighted directed graphs. A directed walk from \(s\) to \(v\) is a sequence of vertices joined by directed edges from each vertex to the next; its weight is the sum of those edge weights. A directed path is a directed walk with no repeated vertices. A directed cycle is a positive-length closed directed walk with no repeated vertices except its first and last. A cycle is negative if the sum of its edge weights is less than zero.
A negative cycle is relevant to the pair \((s,v)\) if it can be reached from \(s\) and \(v\) can be reached from that cycle. Repeating such a cycle makes the weight of an \(s\)-to-\(v\) walk arbitrarily small. This is why distances must be defined using walks, not just paths.
| Situation | Suitable method | Key condition |
|---|---|---|
| One source; all edge weights nonnegative | Dijkstra | No negative edge weights |
| One source; graph is a directed acyclic graph | Topological-order relaxation | Negative weights are allowed |
| One source; general directed graph with possible negative weights | Bellman–Ford | Report vertices whose distances are unbounded below |
| Distances for every ordered pair | Floyd–Warshall | Finite shortest distances require no relevant negative cycles |
Why the Main Choices Work
Proof. Maintain tentative labels, initially \(0\) at \(s\) and \(\infty\) elsewhere. When a vertex \(u\) is settled, relax each outgoing edge \(uw\) by replacing the label of \(w\) by the smaller of its current label and the label of \(u\) plus the weight of \(uw\). Every finite tentative label is the weight of an actual walk from \(s\), so it is at least \(d(s,w)\). We prove by induction on the settling order that each settled label is its true distance. This holds for \(s\), since all edge weights are nonnegative and no walk from \(s\) back to \(s\) has negative weight. Now let \(u\) be the next unsettled vertex with least finite label. Take a shortest path from \(s\) to \(u\), which exists because nonnegative cycles can be removed without increasing a walk’s weight. Let \(x\) be the first unsettled vertex on this path and \(y\) its predecessor. The predecessor \(y\) is settled, so by induction its label is \(d(s,y)\). When \(y\) was settled, relaxing \(yx\) gave \(x\) a label at most the weight of the path prefix from \(s\) to \(x\). That prefix has weight at most \(d(s,u)\), because the remaining path edges have nonnegative weights. Thus \(u\)’s label, being no greater than \(x\)’s label, is at most \(d(s,u)\). It is also at least \(d(s,u)\), since it is the weight of a walk. Equality follows. If no finite unsettled label remains, no unsettled vertex is reachable: any path to one would have a first unsettled vertex reached by an edge from a settled vertex, which would have received a finite label. \(\square\)
Proof. A topological order lists the vertices so that every directed edge goes from an earlier vertex to a later one. For each vertex \(v\), every path from \(s\) to \(v\) ends with an edge \(uv\) whose tail \(u\) occurs earlier. When \(u\) is processed, its distance has already been computed, so relaxing \(uv\) considers the weight of every such path. Taking the minimum over incoming edges therefore gives the minimum path weight to \(v\). If \(v=s\), the empty walk has weight \(0\), which is included as a candidate; if no path reaches \(v\), its label stays \(\infty\). A directed acyclic graph has no directed cycles, so no walk can revisit a vertex; the minimum over walks is thus obtained among paths. The argument uses the order of edges, not the signs of their weights. \(\square\)
Worked Examples
Worked Example: Dijkstra for a Single Source
Let \(G=(V,E)\) be a directed graph with \(V=\{s,a,b,c,t\}\) and edges \(s\to a\) of weight \(4\), \(s\to b\) of weight \(1\), \(b\to a\) of weight \(2\), \(a\to c\) of weight \(1\), \(b\to c\) of weight \(5\), \(a\to t\) of weight \(7\), \(c\to t\) of weight \(3\), and \(b\to t\) of weight \(10\). All weights are nonnegative, so use Dijkstra’s algorithm from \(s\). When labels tie, either tied vertex may be settled first.
| Action | Labels after the action (predecessor) |
|---|---|
| Initialize | \(s=0;\ a=\infty;\ b=\infty;\ c=\infty;\ t=\infty\) |
| Settle \(s\); relax its edges | \(s=0;\ a=4(s);\ b=1(s);\ c=\infty;\ t=\infty\) |
| Settle \(b\); relax its edges | \(s=0;\ a=3(b);\ b=1(s);\ c=6(b);\ t=11(b)\) |
| Settle \(a\); relax its edges | \(s=0;\ a=3(b);\ b=1(s);\ c=4(a);\ t=10(a)\) |
| Settle \(c\); relax its edge | \(s=0;\ a=3(b);\ b=1(s);\ c=4(a);\ t=7(c)\) |
| Settle \(t\) | \(s=0;\ a=3(b);\ b=1(s);\ c=4(a);\ t=7(c)\) |
For example, settling \(b\) changes \(a\) to \(\min(4,1+2)=3\), \(c\) to \(\min(\infty,1+5)=6\), and \(t\) to \(\min(\infty,1+10)=11\). Settling \(a\) then changes \(c\) to \(\min(6,3+1)=4\) and \(t\) to \(\min(11,3+7)=10\). Settling \(c\) changes \(t\) to \(\min(10,4+3)=7\).
The predecessor chains give paths \(s\to b\) to \(b\), \(s\to b\to a\) to \(a\), \(s\to b\to a\to c\) to \(c\), and \(s\to b\to a\to c\to t\) to \(t\). Their weights are, respectively, \(1\), \(1+2=3\), \(1+2+1=4\), and \(1+2+1+3=7\). Each path weight matches its label. As a further check, the final incoming-edge candidates are: \(a\), \(\min(4,1+2)=3\); \(b\), \(1\); \(c\), \(\min(3+1,1+5)=4\); and \(t\), \(\min(3+7,4+3,1+10)=7\).
Worked Example: Negative Edges in a Directed Acyclic Graph
Let \(G=(V,E)\) be the directed graph with \(V=\{s,a,b,c,t\}\) and edges \(s\to a\) of weight \(2\), \(s\to b\) of weight \(5\), \(a\to b\) of weight \(-4\), \(a\to c\) of weight \(3\), \(b\to c\) of weight \(2\), \(b\to t\) of weight \(6\), and \(c\to t\) of weight \(1\). It is acyclic: \(s,a,b,c,t\) is a topological order. Use topological-order relaxation, not Dijkstra.
| Vertex processed | Updates made | Labels afterward |
|---|---|---|
| Initialize | None | \(s=0;\ a=\infty;\ b=\infty;\ c=\infty;\ t=\infty\) |
| \(s\) | \(a=\min(\infty,0+2)=2;\ b=\min(\infty,0+5)=5\) | \(s=0;\ a=2;\ b=5;\ c=\infty;\ t=\infty\) |
| \(a\) | \(b=\min(5,2-4)=-2;\ c=\min(\infty,2+3)=5\) | \(s=0;\ a=2;\ b=-2;\ c=5;\ t=\infty\) |
| \(b\) | \(c=\min(5,-2+2)=0;\ t=\min(\infty,-2+6)=4\) | \(s=0;\ a=2;\ b=-2;\ c=0;\ t=4\) |
| \(c\) | \(t=\min(4,0+1)=1\) | \(s=0;\ a=2;\ b=-2;\ c=0;\ t=1\) |
| \(t\) | No outgoing edges | \(s=0;\ a=2;\ b=-2;\ c=0;\ t=1\) |
The predecessor chain to \(t\) is \(s\to a\to b\to c\to t\), of weight \(2+(-4)+2+1=1\). The label for \(b\) is checked by comparing its incoming options: \(5\) via \(s\), or \(2+(-4)=-2\) via \(a\). For \(c\), the candidates are \(2+3=5\) via \(a\) and \(-2+2=0\) via \(b\). For \(t\), they are \(-2+6=4\) via \(b\) and \(0+1=1\) via \(c\). These minima verify the computed labels.
Worked Example: Bellman–Ford and a Relevant Negative Cycle
Let \(G=(V,E)\) have \(V=\{s,a,b,t\}\) and directed edges \(s\to a\) of weight \(1\), \(a\to b\) of weight \(-3\), \(b\to a\) of weight \(1\), and \(s\to t\) of weight \(5\). The cycle \(a\to b\to a\) has weight \(-3+1=-2\), is reachable from \(s\), and can be repeated. It cannot reach \(t\), because \(t\) has no outgoing edges and its only incoming edge is \(s\to t\). Use Bellman–Ford from \(s\), processing edges in the order listed.
| Stage | \(s\) | \(a\) | \(b\) | \(t\) |
|---|---|---|---|---|
| Initialize | 0 | \(\infty\) | \(\infty\) | \(\infty\) |
| After pass 1 | 0 | \(-1\) | \(-2\) | 5 |
| After pass 2 | 0 | \(-3\) | \(-4\) | 5 |
| After pass 3 | 0 | \(-5\) | \(-6\) | 5 |
In pass 1, \(s\to a\) gives \(a=1\); then \(a\to b\) gives \(b=1-3=-2\); \(b\to a\) gives \(a=-2+1=-1\); and \(s\to t\) gives \(t=5\). In pass 2, the first two cycle-edge relaxations give \(b=-1-3=-4\) and then \(a=-4+1=-3\); \(t\) stays \(5\). In pass 3 they give \(b=-3-3=-6\) and \(a=-6+1=-5\); \(t\) again stays \(5\).
A further scan still improves a label: \(a\to b\) would change \(b\) from \(-6\) to \(-5-3=-8\). This confirms the reachable negative cycle. Repeating it makes \(d(s,a)=d(s,b)=-\infty\). The target \(t\), however, has distance \(5\): the direct walk has weight \(5\), and no walk through \(a\) or \(b\) can reach \(t\). Thus a reachable negative cycle does not make every target’s distance unbounded below.
All-Pairs Queries and Floyd–Warshall
When the question asks for distances between every ordered pair, Floyd–Warshall systematically allows more vertices as intermediate points. Number the vertices \(v_1,\ldots,v_n\). Let \(D^{(k)}[i,j]\) be the minimum weight of a \(v_i\)-to-\(v_j\) path whose internal vertices are among \(v_1,\ldots,v_k\). With no allowed intermediate vertices, the entries are \(0\) on the diagonal, the edge weight for a direct edge, and \(\infty\) when there is no direct edge. The update is
This recurrence compares paths that do not use \(v_k\) internally with paths that do. When there is no negative cycle, a shortest walk can be chosen as a path, so it uses \(v_k\) at most once internally; splitting there gives the second candidate. A negative cycle means some all-pairs distances may be \(-\infty\), so ordinary finite-distance output must be interpreted with that condition in mind.
Worked Example: Floyd–Warshall for All Pairs
Let \(G=(V,E)\) be the directed graph with \(V=\{p,q,r\}\) and edges \(p\to q\) of weight \(4\), \(p\to r\) of weight \(10\), \(q\to r\) of weight \(2\), and \(r\to p\) of weight \(3\). There is no negative cycle: the simple directed cycles are \(p\to r\to p\), of weight \(10+3=13\), and \(p\to q\to r\to p\), of weight \(4+2+3=9\). Compute \(D^{(0)},D^{(1)},D^{(2)},D^{(3)}\), allowing \(p,q,r\) in that order.
The initial matrix, with rows and columns ordered \(p,q,r\), is
Allowing \(p\) as an intermediate point improves \(r\to q\) from \(\infty\) to \(3+4=7\). No other entry improves, so
Allowing \(q\) improves \(p\to r\) from \(10\) to \(4+2=6\). Hence
Allowing \(r\) improves \(q\to p\) from \(\infty\) to \(2+3=5\). The other candidates do not improve their current entries: \(p\to p\) via \(r\) has weight \(6+3=9\), greater than \(0\); \(p\to q\) via \(r\) has weight \(6+7=13\), greater than \(4\); \(q\to q\) via \(r\) has weight \(2+7=9\), greater than \(0\); \(q\to r\) via \(r\) has weight \(2+0=2\); \(r\to p\) via \(r\) has weight \(0+3=3\); and \(r\to r\) via \(r\) has weight \(0\). Thus
Check the nontrivial routes: \(p\to r\) uses \(p\to q\to r\), of weight \(4+2=6\); \(q\to p\) uses \(q\to r\to p\), of weight \(2+3=5\); and \(r\to q\) uses \(r\to p\to q\), of weight \(3+4=7\). The remaining off-diagonal entries are direct edges of weights \(4,2,3\), each smaller than any route that first takes another available edge and returns or continues. The diagonal entries are \(0\); the listed cycle weights are positive, so no cycle improves them.
Common Pitfall: Applying Dijkstra with a Negative Edge
Dijkstra’s method is not justified merely because the graph is directed or because most weights are positive. For a concrete failure, take \(V=\{s,a,b,t\}\) with edges \(s\to a\) of weight \(2\), \(s\to b\) of weight \(5\), \(b\to a\) of weight \(-6\), \(a\to t\) of weight \(2\), and \(b\to t\) of weight \(1\). If Dijkstra settles \(a\) at label \(2\), it can give \(t\) label \(2+2=4\), then settle \(t\) before \(b\), whose label is \(5\). But the path \(s\to b\to a\to t\) has weight \(5-6+2=1\), so \(4\) is wrong. The correction is to check the weight condition before choosing the method: this graph has a negative edge, so use Bellman–Ford (or a specialized method if its structure permits one).
For a reliable choice, first determine whether the query is single-source or all-pairs. For a single source, check whether all weights are nonnegative; if so, Dijkstra applies. If negative weights occur, check whether the graph is acyclic; if it is, use topological-order relaxation. Otherwise use Bellman–Ford and interpret any detected negative cycle in relation to the target vertices. For all-pairs queries, use Floyd–Warshall and check whether negative cycles affect the pairs of interest. After computing, verify path weights from their edges and compare each label with the relevant incoming-edge candidates.
Check Your Understanding
For each question, identify the method or explain the issue, and support the answer with the stated conditions.
- A single-source problem has only nonnegative edge weights. Which method applies, and what property of the weights supports its correctness?
- A directed acyclic graph has some negative edges. Which method applies, and why is Dijkstra not required?
- In the Bellman–Ford example, why does the reachable negative cycle make the distances to \(a\) and \(b\) unbounded below but not the distance to \(t\)?
- In the Floyd–Warshall example, calculate the route weight from \(q\) to \(p\) and explain which intermediate vertex enables it.
- Give the weight of the path \(s\to b\to a\to t\) in the pitfall example. Why can Dijkstra’s settled label for \(t\) fail to account for it?