FINITE MATHEMATICS • LOGIC, SETS, AND NETWORKS

Shortest Paths — Compute shortest paths conceptually and with basic algorithms (intro)

Discover how graph theory finds optimal routes through weighted networks using foundational algorithms.

Historical Context & Motivation

The problem of finding the shortest path through a network is one of the most fundamental questions in discrete mathematics and computer science. While humans have intuitively optimized routes for millennia—ancient trade routes, Roman road networks, and postal systems all reflect an instinctive drive to minimize travel cost—the formal mathematical treatment of shortest-path problems only crystallized in the twentieth century alongside the rise of graph theory and operations research. The urgency of wartime logistics and the advent of digital computers created a fertile environment for researchers to develop algorithms that could efficiently solve routing problems on networks with thousands or even millions of nodes.

The story of shortest-path algorithms is intertwined with the broader development of combinatorial optimization. Leonhard Euler's 1736 solution to the Königsberg bridge problem established graph theory as a discipline, but it was the demands of twentieth-century infrastructure—telephone routing, airline scheduling, and military supply chains—that drove the creation of practical shortest-path algorithms. These algorithms remain indispensable today, powering everything from GPS navigation to internet packet routing and social-network analysis.

1736
Euler and the Königsberg Bridges
Leonhard Euler formalized the concept of a graph by proving that no walk could cross each of Königsberg's seven bridges exactly once. This landmark paper inaugurated graph theory as a mathematical discipline.
1956
Dijkstra's Algorithm Conceived
Dutch computer scientist Edsger W. Dijkstra devised his famous shortest-path algorithm in roughly twenty minutes while sitting at a café in Amsterdam. Published in 1959, the algorithm efficiently finds the shortest path from a single source to all other vertices in a graph with non-negative edge weights.
1958
Bellman–Ford Algorithm
Richard Bellman and Lester Ford Jr. independently developed an algorithm that handles graphs with negative edge weights, trading speed for generality compared to Dijkstra's method.
1962
Floyd–Warshall Algorithm
Robert Floyd and Stephen Warshall published an elegant dynamic-programming algorithm that computes shortest paths between all pairs of vertices simultaneously, a natural fit for dense networks.
2000s
Modern Applications at Scale
Shortest-path algorithms now underpin GPS navigation (Google Maps, Waze), internet routing protocols (OSPF, IS-IS), and social-network analytics, operating on graphs with billions of edges.

The central question these developments address is deceptively simple: given a network of locations connected by paths of varying costs, what is the least-cost route between two specified locations? Answering this question rigorously requires a formal vocabulary of vertices, edges, and weights, as well as systematic algorithmic strategies—topics we develop in the sections that follow.

Core Principles & Definitions

Before tackling algorithms, we must establish the formal language of weighted graphs. A weighted graph G = (V, E, w) consists of a set V of vertices (also called nodes), a set E of edges connecting pairs of vertices, and a weight function w : E → ℝ that assigns a numerical cost (distance, time, price, etc.) to each edge. A path in G is a sequence of vertices v₁, v₂, …, vₖ where each consecutive pair (vᵢ, vᵢ₊₁) is an edge in E. The length (or cost) of a path is the sum of the weights of its constituent edges.

1

Weighted Graph

A graph G = (V, E, w) where every edge e ∈ E carries a real-valued weight w(e). Weights model distance, time, monetary cost, or any additive metric.
2

Path & Path Length

A sequence of vertices connected by edges. The path length equals the sum of all edge weights along the path: ∑ w(vᵢ, vᵢ₊₁).
3

Shortest Path

Among all paths from vertex s to vertex t, the one with minimum total weight. It may not be unique—multiple paths can share the same minimum cost.
4

Optimal Substructure

A sub-path of a shortest path is itself a shortest path between its endpoints. This principle is the theoretical backbone of every shortest-path algorithm.
5

Relaxation

The operation of checking whether a newly discovered route through an intermediate vertex improves the current best-known distance to a target vertex, updating the distance if so.
KEY TAKEAWAY
Think of optimal substructure like planning the cheapest multi-leg flight from New York to Tokyo. If the cheapest overall itinerary routes you through Chicago and then Seoul, then the New York → Chicago leg must itself be the cheapest way to reach Chicago, and the Chicago → Seoul leg must be cheapest from Chicago to Seoul. If either sub-leg were not optimal, you could swap it for a cheaper alternative and reduce the total fare—contradicting the assumption that the overall route was cheapest. Shortest-path algorithms exploit precisely this decomposability, building globally optimal solutions from locally optimal pieces.

Visual Explanation — A Weighted Graph

The diagram below presents a small weighted graph with six vertices (A through F) and nine edges. Each edge is labeled with its weight. The highlighted path from A to F illustrates the shortest route, whose total cost is 9. Notice that this path does not necessarily use the fewest edges; the shortest path by edge count (A → B → F, with two edges) has a total weight of 14, which is suboptimal. This underscores a crucial distinction: shortest path refers to minimum total weight, not minimum number of edges.

A weighted graph on vertices A–F. The cyan-highlighted edges trace the shortest path from A to F with total weight 9. Alternative routes, such as A → B → F (weight 7 + 7 = 14) or A → C → E → D → F (weight 2 + 3 + 2 + 6 = 13), cost more.

In the diagram, vertex A serves as the source and vertex F is the destination. The cyan path A → C → E → F achieves a total cost of 2 + 3 + 4 = 9, which is strictly less than every other A-to-F path. Observe that the path passes through three edges and four vertices; a different path, A → B → F, uses only two edges but carries a total weight of 14. The key lesson is that greedy choices on individual edges do not guarantee global optimality—the cheapest first step from A leads to C (weight 2), and continuing greedily from C leads to E (weight 3), then E to F (weight 4). In this particular instance, the greedy heuristic happens to yield the shortest path, but in general, a systematic algorithm is required.

Mathematical Framework

We now formalize the shortest-path problem and introduce the two most important introductory algorithms: Dijkstra's algorithm for graphs with non-negative weights and a brief look at the Bellman–Ford algorithm for more general cases. Both algorithms rely on the principle of relaxation and optimal substructure described earlier.

SHORTEST PATH DEFINITION
δ(s, t) = min { ∑ᵢ w(vᵢ, vᵢ₊₁) : P is a path from s to t }
δ(s, t) denotes the shortest-path distance from source vertex s to target vertex t. P ranges over all paths from s to t; the minimum is taken over the sum of edge weights along each path. If no path exists, δ(s, t) = ∞.
RELAXATION OPERATION
If d[u] + w(u, v) < d[v], then set d[v] ← d[u] + w(u, v)
Here d[v] is the current best-known distance to vertex v. When we discover that routing through vertex u yields a cheaper path to v, we update d[v]. This operation is the atomic building block of both Dijkstra's and Bellman–Ford algorithms.

Dijkstra's Algorithm Outline

Dijkstra's algorithm maintains a set S of vertices whose shortest distances from the source are finalized, and a priority queue Q of remaining vertices keyed by tentative distances. Initially, d[s] = 0 and d[v] = ∞ for all v ≠ s. At each iteration, the vertex u with the smallest tentative distance is extracted from Q and added to S. Then, for every neighbor v of u, the edge (u, v) is relaxed. The process repeats until Q is empty. Because each extraction is provably optimal (a consequence of non-negative weights), the algorithm correctly computes δ(s, v) for every vertex v.

DIJKSTRA TIME COMPLEXITY
O((|V| + |E|) log |V|) with a binary-heap priority queue
|V| is the number of vertices and |E| is the number of edges. Each vertex is extracted from the heap once (O(|V| log |V|)), and each edge triggers at most one decrease-key operation (O(|E| log |V|)).

Bellman–Ford Algorithm Outline

The Bellman–Ford algorithm is simpler but slower. It initializes d[s] = 0 and d[v] = ∞ for v ≠ s, then performs |V| − 1 passes over every edge, relaxing each one. After |V| − 1 rounds, all shortest-path distances are finalized. A final (|V|-th) pass checks for negative-weight cycles: if any edge can still be relaxed, a negative cycle exists and no finite shortest path is defined. The running time is O(|V| × |E|), which is slower than Dijkstra's but handles negative edge weights.

BELLMAN–FORD TIME COMPLEXITY
O(|V| × |E|)
Each of the |V| − 1 passes iterates over all |E| edges. This is typically slower than Dijkstra's algorithm but allows negative weights.

Detailed Breakdown — Tracing Dijkstra's Algorithm

To solidify understanding, let us trace Dijkstra's algorithm step by step on the graph from Section 3. We seek the shortest path from vertex A (the source) to every other vertex. The diagram below captures the state of the distance labels and finalized set after each extraction.

Step-by-step trace of Dijkstra's algorithm on the graph from Section 3. Yellow entries indicate distance updates via relaxation; cyan entries with ✓ indicate finalized (extracted) distances. The set S grows by one vertex each iteration.

Each iteration of the algorithm extracts the vertex with the smallest tentative distance from the priority queue and finalizes it. In iteration 1, we extract A (distance 0) and relax edges to B (d[B] updated to 7) and C (d[C] updated to 2). In iteration 2, C is extracted at distance 2, and relaxation reaches E (d[E] = 2 + 3 = 5) and B (no improvement since 2 + 6 = 8 > 7). The process continues until every vertex is finalized. The total cost to reach F is confirmed as δ(A, F) = 9, achieved via the path A → C → E → F.

Worked Example — Finding the Shortest Path

Consider a new graph with five cities connected by roads of varying lengths. We wish to find the shortest path from city S to city T using Dijkstra's algorithm. The edges and weights are: S–A (4), S–B (1), A–B (2), A–C (5), B–A (1), B–C (8), C–T (3), A–T (12).

Dijkstra's Algorithm: S → T
1
Step 1 — InitializeSet d[S] = 0. Set d[A] = d[B] = d[C] = d[T] = ∞. The priority queue Q contains all five vertices. The finalized set S is empty.
d = {S:0, A:∞, B:∞, C:∞, T:∞}
2
Step 2 — Extract S (d = 0)Extract vertex S from Q. Relax edges S–A and S–B. d[A] ← min(∞, 0 + 4) = 4. d[B] ← min(∞, 0 + 1) = 1. Add S to finalized set.
d = {S:0✓, A:4, B:1, C:∞, T:∞}
3
Step 3 — Extract B (d = 1)B has the smallest tentative distance. Relax B–A: d[A] ← min(4, 1 + 1) = 2 (improved!). Relax B–C: d[C] ← min(∞, 1 + 8) = 9.
d = {S:0✓, A:2, B:1✓, C:9, T:∞}
4
Step 4 — Extract A (d = 2)Extract A. Relax A–C: d[C] ← min(9, 2 + 5) = 7 (improved!). Relax A–T: d[T] ← min(∞, 2 + 12) = 14. Relax A–B: d[B] = 1 is already finalized, so no update.
d = {S:0✓, A:2✓, B:1✓, C:7, T:14}
5
Step 5 — Extract C (d = 7)Extract C. Relax C–T: d[T] ← min(14, 7 + 3) = 10 (improved!). C is now finalized.
d = {S:0✓, A:2✓, B:1✓, C:7✓, T:10}
6
Step 6 — Extract T (d = 10)T is extracted and finalized. All vertices are now in the finalized set. The shortest path from S to T has total weight 10. By tracing predecessors: T was reached from C (d = 7 + 3), C from A (d = 2 + 5), A from B (d = 1 + 1), and B from S (d = 0 + 1).
Shortest path: S → B → A → C → T, total weight = 10
💡 Notice the Power of Relaxation
Vertex A's distance was updated twice—first to 4 (via S–A) and then to 2 (via S–B–A). Similarly, vertex C improved from 9 to 7, and T from 14 to 10. Each relaxation brought the tentative distance closer to the true shortest distance. This iterative refinement is what makes the algorithm correct.

Strengths, Limitations & Algorithm Comparisons

No single shortest-path algorithm dominates in all scenarios. The choice of algorithm depends on the structure of the graph (sparse vs. dense), the presence or absence of negative edge weights, and whether you need shortest paths from one source or between all pairs of vertices. The table below compares the three foundational algorithms introduced in this lesson.

Comparison of introductory shortest-path algorithms
FeatureDijkstra'sBellman–FordFloyd–Warshall
Problem typeSingle-sourceSingle-sourceAll-pairs
Negative weights?NoYesYes (no neg. cycles)
Detects neg. cycles?NoYesYes (via diagonal)
Time complexityO((V+E) log V)O(V × E)O(V³)
Best suited forSparse, non-negative graphsGraphs with negative edgesSmall, dense graphs; all-pairs queries
Ease of implementationModerate (priority queue)Simple (nested loops)Very simple (triple loop)
KEY TAKEAWAY
Choosing a shortest-path algorithm is like choosing a vehicle for a trip. Dijkstra's algorithm is a sports car—fast and efficient on well-paved highways (non-negative weights), but it cannot handle rough terrain (negative edges). Bellman–Ford is an all-terrain vehicle—slower but capable of navigating any landscape, including detecting treacherous loops (negative cycles). Floyd–Warshall is a fleet of taxis dispatched to cover every possible origin-destination pair—comprehensive but resource-intensive. Match the algorithm to the problem's constraints.

Connection to Advanced Theory

The introductory algorithms covered here form the foundation for a rich ecosystem of advanced shortest-path techniques. As networks grow to billions of nodes—think continental road maps or the global internet—vanilla Dijkstra becomes impractical, motivating sophisticated extensions. Understanding the basic versions equips you to appreciate the design rationale behind these more powerful tools.

From introductory to advanced shortest-path techniques
Introductory ConceptAdvanced Extension
Dijkstra's with binary heapDijkstra's with Fibonacci heap — O(V log V + E) amortized time
Single-source shortest pathsA* search — uses heuristic estimates to guide exploration toward the goal, dramatically reducing vertices examined
Static edge weightsDynamic / time-dependent shortest paths — weights change over time (e.g., traffic congestion models)
Exact shortest pathContraction Hierarchies and ALT algorithms — preprocess the graph for near-instantaneous point-to-point queries
Non-negative weights only (Dijkstra)Johnson's algorithm — reweights edges using Bellman–Ford to eliminate negative weights, then runs Dijkstra from each source

In subsequent coursework you may encounter these extensions, particularly A* search in artificial intelligence and network flow problems in operations research, which generalize shortest paths to find maximum throughput in capacitated networks. The same principles of relaxation, optimal substructure, and systematic exploration underpin all of these methods. Mastering Dijkstra's and Bellman–Ford provides the conceptual scaffolding on which every advanced routing algorithm is built.

Practice Problems

PROBLEM 1CONCEPTUAL
Explain why Dijkstra's algorithm fails to produce correct shortest-path distances when the graph contains a negative-weight edge. Provide a simple three-vertex example to illustrate your argument.
PROBLEM 2BASIC CALCULATION
Consider a graph with vertices {1, 2, 3, 4} and edges: (1,2) weight 3, (1,3) weight 10, (2,3) weight 1, (2,4) weight 8, (3,4) weight 2. Apply Dijkstra's algorithm from source vertex 1 and determine δ(1, v) for every vertex v.
PROBLEM 3INTERMEDIATE
A directed graph has vertices {S, A, B, C, T} with edges: S→A (2), S→B (5), A→B (1), A→C (7), B→C (3), B→T (9), C→T (1). Two students propose different shortest S→T paths: Student X says S→A→C→T (cost 10) and Student Y says S→A→B→C→T (cost 7). Verify which student is correct by running Dijkstra's algorithm.
PROBLEM 4APPLIED
A delivery company operates between five warehouses. Driving times (in minutes) are: W1→W2 (15), W1→W3 (30), W2→W3 (10), W2→W4 (25), W3→W4 (5), W3→W5 (20), W4→W5 (10). A truck at W1 must reach W5 as quickly as possible. Determine the fastest route and its total travel time. Would the answer change if the road W3→W4 were closed for construction?
PROBLEM 5CRITICAL THINKING
Prove that if all edge weights in a connected graph are distinct (no two edges share the same weight), then the shortest path between any pair of vertices is unique. (Hint: argue by contradiction.)

Lesson Summary

The shortest-path problem asks for the minimum-weight route between vertices in a weighted graph G = (V, E, w). The two key structural insights are optimal substructure (sub-paths of shortest paths are themselves shortest) and relaxation (iteratively tightening tentative distance estimates). Dijkstra's algorithm solves the single-source problem in O((V+E) log V) time for graphs with non-negative edge weights, greedily extracting the closest unfinalized vertex and relaxing its neighbors.

When negative edge weights are present, the Bellman–Ford algorithm provides a correct (if slower) alternative in O(V × E) time, with the added ability to detect negative-weight cycles. For all-pairs shortest paths, the Floyd–Warshall algorithm runs in O(V³) and is particularly elegant for small, dense graphs. These foundational algorithms underpin modern applications from GPS navigation to network routing and serve as the conceptual gateway to advanced techniques such as A* search and contraction hierarchies.

Varsity Tutors • Finite Mathematics • Shortest Paths — Compute shortest paths conceptually and with basic algorithms (intro)