Lecture 22
Weighted Graphs
Lecture 20 used an adjacency list where each entry was just a neighbor index. Weighted graphs attach a numeric cost to each edge. The adjacency list now stores {neighbor, weight} pairs.
All three algorithms in this lecture find shortest paths in weighted directed graphs. They differ in what they can handle and how fast they run.
Relaxation
Relaxation is the operation every shortest-path algorithm is built on. Given a known tentative distance to vertex u and an edge u → v with weight w, we check whether routing through u improves the known distance to v:
Dijkstra's applies relaxation greedily in order of current distance. Bellman-Ford applies it exhaustively across all edges, repeatedly.
Dijkstra's Algorithm
Dijkstra's finds the shortest path from a single source to all other vertices in a graph with non-negative edge weights. It is the graph analogue of BFS — where BFS explores by hop count, Dijkstra's explores by accumulated cost.
The algorithm uses a min-heap priority queue keyed on current distance. When a vertex is popped, its distance is finalized. Any later entry for the same vertex in the queue is stale and skipped.
Dijkstra's trace on a 5-vertex graph:
The shortest path to vertex 1 is not the direct edge (cost 4) but the path 0 → 2 → 1 (cost 3). Dijkstra's finds this because vertex 2 is finalized first — its distance is smaller — and relaxation through 2 improves vertex 1 before vertex 1 is popped from the queue.
Dijkstra's is incorrect on graphs with negative edge weights. A finalized vertex might later be reachable via a negative edge at a lower cost, but the algorithm never revisits finalized vertices. Use Bellman-Ford when negative weights are present.
Bellman-Ford
Bellman-Ford finds single-source shortest paths and handles negative edge weights. It also detects negative cycles — cycles whose total weight is negative, which would make the shortest path unbounded.
The algorithm works by relaxing every edge V−1 times. A shortest path can contain at most V−1 edges (visiting each vertex at most once), so V−1 passes guarantee all shortest paths are found. A Vth pass that still improves a distance reveals a negative cycle.
Bellman-Ford trace on a 4-vertex graph with a negative edge:
Notice that the best path to vertex 1 goes through vertex 2 (0 → 2 → 1, cost 4), exploiting the negative edge. Dijkstra's would finalize vertex 1 at cost 6 before discovering this cheaper route.
Floyd-Warshall
Floyd-Warshall solves the all-pairs shortest path problem: the shortest distance between every pair of vertices simultaneously. It works by progressively allowing more intermediate vertices into candidate paths.
For each intermediate vertex k, it checks whether routing through k improves any path i → j:
The crucial detail is that k must be the outermost loop. Only when k is fixed do the inner loops correctly query paths that are allowed to use only vertices 0..k as intermediates.
Comparison
| Algorithm | Time | Space | Negative weights | Negative cycle detection | Use case |
|---|---|---|---|---|---|
| Dijkstra's | O((V+E) log V) | O(V) | No | No | Single-source, dense maps |
| Bellman-Ford | O(VE) | O(V) | Yes | Yes | Single-source, general |
| Floyd-Warshall | O(V³) | O(V²) | Yes | Yes (negative diagonal) | All-pairs, small graphs |
Exercises
Q1.
Without running the code, predict what this program prints.
Q2.
Without running the code, predict what this program prints.
Q3.
Each snippet has a bug. Identify what's wrong.
Q4.
Implement dijkstra for the weighted graph below.
Q5.
Implement bellman_ford for the edge list below.
Practice Problems
- Network Delay Time — Medium
- Path with Minimum Effort — Medium
- Cheapest Flights Within K Stops — Medium
- Find the City With the Smallest Number of Neighbors at a Threshold Distance — Medium