Dijkstra's algorithm
A weighted directed graph is stored as a dictionary of dictionaries: graph[a][b] is the cost of the edge from a to b. All costs are non-negative. Write dijkstra(graph, start) that returns the shortest distance from start to every reachable node.
graph = {
"A": {"B": 4, "C": 1},
"B": {"D": 1},
"C": {"B": 2, "D": 5},
"D": {},
}
dijkstra(graph, "A")
# {"A": 0, "C": 1, "B": 3, "D": 4}
Show hint
Always expand the unvisited node with the smallest known distance. A heap (heapq) gives you that node quickly.
Show solution
import heapq
def dijkstra(graph, start):
dist = {start: 0}
heap = [(0, start)]
while heap:
d, node = heapq.heappop(heap)
if d > dist[node]:
continue # an outdated entry
for nxt, cost in graph[node].items():
nd = d + cost
if nd < dist.get(nxt, float("inf")):
dist[nxt] = nd
heapq.heappush(heap, (nd, nxt))
return dist
The direct edge A to B costs 4, but A to C to B costs 3, so B's distance is improved after C is processed. Rather than updating entries inside the heap, this version pushes a new entry and skips stale ones when they are popped. Runtime is O((V + E) log V). It needs non-negative costs; with negative edges, use Bellman-Ford. Map apps and network routing are built on this idea.
Want a problem like this every day? See today's problem and keep a streak going.