Dijkstra's Algorithm
Find shortest paths from a source vertex in a weighted graph with non-negative edges.
The Mathematics
Greedy relaxation, priority queue, and shortest-path optimality
Problem Definition
Given a weighted directed graph with non-negative edge weights and a source vertex , find the shortest path distance from to every other vertex:
Relaxation
The key operation: if we find a shorter path to via , update the estimate:
This is called “relaxing” the edge . When no more relaxations are possible, all distances are optimal.
Greedy Strategy
Dijkstra's key insight: always process the unvisited vertex with the smallest tentative distance. This greedy choice is correct because edge weights are non-negative — no future path can improve the current minimum:
A min-priority queue efficiently finds this minimum.
Complexity
With a binary min-heap priority queue:
Each vertex is extracted once () and each edge triggers at most one priority queue update (). With a Fibonacci heap this improves to .
See It Work
Dijkstra's algorithm from source A — greedy relaxation with a priority queue
Priority Queue (min-heap)
Initialize: set dist(A) = 0, all others = ∞. Push source A into the priority queue.
The Code
Mapping greedy relaxation to Python with heapq
Mathematical Formulation
Initialize source distance to 0, all others to infinity
Greedily extract the vertex with smallest tentative distance
Skip already-finalized vertices (stale PQ entries)
Check all outgoing edges from the current vertex
Relaxation: update distance if a shorter path is found
Python Implementation
import heapq
def dijkstra(graph, source):
dist = {v: float('inf') for v in graph}
dist[source] = 0 # Source distance
pq = [(0, source)] # Priority queue
visited = set()
while pq:
d, v = heapq.heappop(pq) # Extract min
if v in visited: continue # Skip stale
visited.add(v)
for u, w in graph[v]: # Check neighbors
if dist[v] + w < dist[u]: # Relaxation
dist[u] = dist[v] + w
heapq.heappush(pq, (dist[u], u))
return dist