Problem Statement
Network Delay Time (Dijkstra)
You have a network of n nodes, numbered 1 to n. Think of nodes as cities and edges as one-way roads. You are given times, a list of roads written as times[i] = (ui, vi, wi), which means a signal can travel from city ui to city vi, and it takes wi units of time to get there. The word "directed" just means each road goes one way only, from ui to vi and not back. You start by sending a signal out from city k. The signal spreads along the roads and reaches more cities over time. Your job is to find the time it takes for every city to have received the signal. Since all cities get it only once the slowest one does, the answer is the time the last city receives it. If some city can never be reached, return -1. The tool we use is Dijkstra's algorithm, a method for finding the shortest travel time from one starting point to every other point. It uses a min-heap, which is a container that always hands you the smallest item first, so we always work on the city we can reach soonest.
Signals to notice
Brute force first
BFS/DFS trying all paths — doesn't account for edge weights properly. That direct path helps you understand the question, but it tends to treat every possibility as brand new instead of learning from earlier steps.
The key insight
Dijkstra's algorithm: min-heap of (distance, node). Process the nearest unvisited node, relax its neighbors. The answer is the maximum distance to any node — that's when the last node receives the signal. The goal is not to be clever for its own sake, but to remember the one relationship that keeps the solution grounded as you move forward.
Trace it on times=[[2,1,1],[2,3,1],[3,4,1]], n=4, k=2
init: graph={2:[(1,1),(3,1)], 3:[(4,1)]}, dist={}, heap=[(0,2)]
pop (0,2): 2 new -> dist={2:0}; push (1,1),(1,3); heap=[(1,1),(1,3)]
pop (1,1): 1 new -> dist={2:0,1:1}; node 1 has no edges; heap=[(1,3)]
pop (1,3): 3 new -> dist={2:0,1:1,3:1}; push (2,4); heap=[(2,4)]
pop (2,4): 4 new -> dist={2:0,1:1,3:1,4:2}; node 4 no edges; heap=[]
heap empty, len(dist)=4 == n=4 -> return max(dist.values())=2What must stay true
Dijkstra's guarantees that when a node is popped from the heap, its distance is final. The signal reaches all nodes when the farthest one is reached — max(distances). If that remains true after every update, the rest of the reasoning has a stable place to stand.
Shape of the loop
heap = [(0, k)]; dist = {}
while heap:
d, node = pop_min(heap)
if node in dist: continue
dist[node] = d
for nbr, w in graph[node]:
if nbr not in dist: push(heap, (d+w, nbr))
return max(dist.values()) if len(dist)==n else -1Pseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Using BFS for weighted graphs — BFS only finds shortest paths in unweighted graphs. Dijkstra's handles variable edge weights correctly. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.