Code Snippets
/

Dijkstra in Python with heapq

Dijkstra in Python with heapq

Dijkstra finds the shortest path in a weighted graph with non-negative edge weights. The Python idiom is `heapq` (a binary min-heap) plus a distance dict, which gives O((V + E) log V) without external libraries. This entry covers the standard single-source template, path reconstruction, and the early-exit shortest-path-to-one-target variant.

Python
Hard
dijkstra
graph-algorithms
min-heap
algorithms

674 views

16

import heapq
from collections import defaultdict

def dijkstra(graph, source):
    """Shortest distance from source to every reachable node.

    graph: dict-of-lists where graph[u] = [(v, weight), ...]
    """
    dist = {source: 0}
    heap = [(0, source)]   # (distance, node)
    while heap:
        d, u = heapq.heappop(heap)
        if d > dist[u]:
            continue       # stale entry left over from a tighter relaxation
        for v, w in graph[u]:
            nd = d + w
            if nd < dist.get(v, float('inf')):
                dist[v] = nd
                heapq.heappush(heap, (nd, v))
    return dist

# Build a small weighted graph.
graph = defaultdict(list)
for u, v, w in [('A', 'B', 4), ('A', 'C', 1), ('C', 'B', 2),
                ('B', 'D', 1), ('C', 'D', 5), ('D', 'E', 3)]:
    graph[u].append((v, w))
    graph[v].append((u, w))   # undirected

print(dijkstra(graph, 'A'))
# {'A': 0, 'C': 1, 'B': 3, 'D': 4, 'E': 7}

# Disconnected: 'X' has no edges, only itself reachable.
lonely = defaultdict(list)
lonely['X'] = []
print(dijkstra(lonely, 'X'))   # {'X': 0}

The heap stores (tentative_distance, node) tuples and heappop always returns the smallest. Because Python's heapq does not support decrease-key, the standard trick is to push a fresh entry every time you find a shorter path and to discard stale pops with the if d > dist[u]: continue guard. This adds at most one stale entry per relaxation, so the heap stays O(E) in size and the total runtime is O((V + E) log V). The algorithm only works for non-negative weights; a single negative edge can produce paths that need to be revisited, which Dijkstra cannot do.

2 more snippets in this entry are available for premium members.

Upgrade to Premium