743. Network Delay Time (Naive Dijkstra)¶
Edited by Charles
Medium · Python · Graph
Problem
Read the original problem on LeetCode.
The official page contains the problem statement, examples, and constraints.
Explanation, examples & other approaches
Core idea
Use Dijkstra's Algorithm to find the shortest distance from the starting node k to every other node.
Original study notes follow, including intermediate snippets and earlier attempts.
Idea¶
Use Dijkstra's Algorithm to find the shortest distance from the starting node k to every other node.
This version uses:
- Adjacency Matrix
- Linear Scan
- Visited Array
It is the naive Dijkstra implementation without a min-heap.
The problem asks how long it takes for the signal to reach all nodes.
So after finding the shortest distance from k to every node, the answer is:
because the total delay is determined by the node that receives the signal last.
If any node is unreachable, return -1.
Graph Representation¶
Each edge:
means:
We use an adjacency matrix:
Then:
So:
represents the travel time from node u to node v.
If:
then there is no direct edge from u to v.
minDist¶
Define:
as:
The shortest distance currently known from the starting node
kto nodei.
Initially:
The starting node has distance 0 from itself.
All other nodes are initially unreachable, so their distances are set to infinity.
Example:
visit¶
Define:
as:
Whether the shortest distance to node
ihas already been finalized.
Initially:
When:
it means the shortest distance from k to node i has been determined and will no longer change.
Step 1: Find the Closest Unvisited Node¶
At each round, find the unvisited node with the smallest current distance:
minVal = float('inf')
cur = -1
for node in range(1, n + 1):
if not visit[node] and minDist[node] < minVal:
minVal = minDist[node]
cur = node
This is the key step of naive Dijkstra.
Among all unvisited nodes, choose the one with the smallest:
Then:
is the next node whose shortest distance can be finalized.
Why Can We Finalize cur?¶
Dijkstra assumes all edge weights are non-negative.
If cur currently has the smallest distance among all unvisited nodes, no other unvisited path can later produce a shorter route to cur.
Therefore:
and:
is now finalized.
Why cur == -1?¶
We initialize:
and only update it when:
Since:
a node whose distance is also inf will not be selected because:
is False.
Therefore, if:
after scanning all nodes, it means every remaining unvisited node has:
In other words:
No remaining node is reachable from the starting node.
So we can stop early:
Step 2: Relax the Neighbors¶
After finalizing cur, try to update all nodes directly reachable from cur.
Suppose:
We already know:
and the edge:
Then the new possible distance to node is:
If this is smaller than the current:
we update it.
In the code:
if (
not visit[node]
and graph[cur][node] != float('inf')
and graph[cur][node] + minDist[cur] < minDist[node]
):
minDist[node] = graph[cur][node] + minDist[cur]
This process is called relaxation.
Relaxation Formula¶
The core transition is:
It compares two possibilities:
- Keep the previously known shortest distance.
- Reach
nodethroughcur.
If going through cur is shorter, update the distance.
Hand Simulation¶
Suppose:
The graph is:
Initially:
Round 1¶
The closest unvisited node is:
because:
Mark it visited:
Relax its neighbors.
For:
we get:
so:
For:
we get:
so:
Now:
Round 2¶
Among unvisited nodes:
The scan finds node 1 first:
Mark:
Node 1 has no outgoing edges, so nothing changes.
Round 3¶
The closest remaining node is:
Mark:
There is an edge:
So:
Now:
Round 4¶
The last node is:
After processing it:
excluding index 0.
Final Answer¶
The signal reaches each node after:
The last node receives the signal after:
which is:
So the answer is:
Why Take the Maximum?¶
Dijkstra gives us the shortest distance from k to every node.
But the problem asks:
How long until every node receives the signal?
All nodes have received the signal only when the slowest node receives it.
Therefore:
Unreachable Nodes¶
If one node cannot be reached from k, its distance remains:
Therefore:
will also be:
So:
Key Idea of Naive Dijkstra¶
Each round performs two operations:
Find¶
Find the closest unvisited node:
Relax¶
Use cur to update its neighbors:
Then repeat.
Memory:
Find the closest unvisited node → finalize it → relax its neighbors → repeat.
Complexity¶
The outer loop runs at most n times.
Each time, we scan all n nodes to find the closest unvisited node:
Then we scan all n nodes again to relax neighbors:
Therefore:
The adjacency matrix requires:
So overall:
Code¶
class Solution:
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
minDist = [float('inf')] * (n + 1)
visit = [False] * (n + 1)
minDist[k] = 0
graph = [[float('inf')] * (n + 1) for _ in range(n + 1)]
for u, v, w in times:
graph[u][v] = w
for _ in range(n):
minVal = float('inf')
cur = -1
for node in range(1, n + 1):
if not visit[node] and minDist[node] < minVal:
minVal = minDist[node]
cur = node
if cur == -1:
break
visit[cur] = True
for node in range(1, n + 1):
if (
not visit[node]
and graph[cur][node] != float('inf')
and graph[cur][node] + minDist[cur] < minDist[node]
):
minDist[node] = graph[cur][node] + minDist[cur]
res = max(minDist[1:])
return -1 if res == float('inf') else res
Study record
| Field | Value |
|---|---|
| Attempts | 1 |
| Mastery | ❚ |
| The Latest Attempt | August 28, 2026 |
Python solution¶
# Deque
class Solution:
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
graph = defaultdict(list)
for u,v,w in times:
graph[u].append((v,w))
distance = [inf] * (n+1)
distance[k] = 0
# visited = [k]
in_queue = [False] * (n+1)
in_queue[k] = True
queue = deque()
queue.append(k)
while queue:
cur = queue.popleft()
in_queue[cur] = False
for nxt,w in graph[cur]:
if distance[cur] + w < distance[nxt]:
distance[nxt] = distance[cur] + w
if not in_queue[nxt]:
queue.append(nxt)
in_queue[nxt] = True
ans = max(distance[1:])
return ans if ans < inf else -1