Tutorials › Graph Theory (Undergraduate) › Choosing And Applying A Shortest-Path Algorithm

Shortest Paths · Tutorial 256 of 799

Choosing And Applying A Shortest-Path Algorithm

Learn to match a shortest-path algorithm to the graph and query, then check its distances, paths and negative-cycle behavior.

Intermediate 11 min read

What You'll Learn

  • Select an algorithm using edge weights, directed acyclicity and whether the query is single-source or all-pairs.
  • Trace Dijkstra’s algorithm and verify its predecessor paths and distances.
  • Apply topological-order relaxation when a directed graph is acyclic, including with negative weights.
  • Use Bellman–Ford to identify vertices affected by reachable negative cycles.
  • Compute and check all-pairs distances with Floyd–Warshall.
  • Recognize why using Dijkstra with negative edge weights can give a wrong answer.

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.

Definition: The distance \(d(s,v)\) is the infimum of the weights of all directed walks from \(s\) to \(v\). If no such walk exists, \(d(s,v)=\infty\). If walks from \(s\) to \(v\) have arbitrarily small weight, \(d(s,v)=-\infty\). A finite distance is attained by a shortest walk; when no relevant negative cycle exists, a shortest walk can be chosen to be a path.

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.

SituationSuitable methodKey condition
One source; all edge weights nonnegativeDijkstraNo negative edge weights
One source; graph is a directed acyclic graphTopological-order relaxationNegative weights are allowed
One source; general directed graph with possible negative weightsBellman–FordReport vertices whose distances are unbounded below
Distances for every ordered pairFloyd–WarshallFinite shortest distances require no relevant negative cycles

Why the Main Choices Work

Theorem (Dijkstra’s algorithm): In a finite weighted directed graph with nonnegative edge weights, Dijkstra’s algorithm computes \(d(s,v)\) for every vertex reachable from the source \(s\). Vertices not reachable from \(s\) have distance \(\infty\).

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\)

Theorem (topological-order relaxation): If a finite weighted directed graph is acyclic, processing its vertices in topological order and relaxing outgoing edges computes all distances from a chosen source, including when some edge weights are negative.

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.

ActionLabels 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 processedUpdates madeLabels afterward
InitializeNone\(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\)
Initialize0\(\infty\)\(\infty\)\(\infty\)
After pass 10\(-1\)\(-2\)5
After pass 20\(-3\)\(-4\)5
After pass 30\(-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

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

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

$$ D^{(0)}= \begin{pmatrix} 0&4&10\\ \infty&0&2\\ 3&\infty&0 \end{pmatrix}. $$

Allowing \(p\) as an intermediate point improves \(r\to q\) from \(\infty\) to \(3+4=7\). No other entry improves, so

$$ D^{(1)}= \begin{pmatrix} 0&4&10\\ \infty&0&2\\ 3&7&0 \end{pmatrix}. $$

Allowing \(q\) improves \(p\to r\) from \(10\) to \(4+2=6\). Hence

$$ D^{(2)}= \begin{pmatrix} 0&4&6\\ \infty&0&2\\ 3&7&0 \end{pmatrix}. $$

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

$$ D^{(3)}= \begin{pmatrix} 0&4&6\\ 5&0&2\\ 3&7&0 \end{pmatrix}. $$

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.

  1. A single-source problem has only nonnegative edge weights. Which method applies, and what property of the weights supports its correctness?
  2. A directed acyclic graph has some negative edges. Which method applies, and why is Dijkstra not required?
  3. 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\)?
  4. In the Floyd–Warshall example, calculate the route weight from \(q\) to \(p\) and explain which intermediate vertex enables it.
  5. 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?