Network Delay Time
A network has n nodes labeled 1 to n. You're given times, a list of directed edges [u, v, w] meaning a signal sent from u reaches v after w units of time. A signal starts at node k. Return how long it takes until every node has received it, or -1 if some node never does.
Examples
times = [[1,2,4],[1,3,1],[3,2,2],[2,4,1]], n = 4, k = 1 returns 4
Node 3 hears at time 1. Node 2 hears at time 3 through node 3, earlier than the direct edge's 4. Node 4 then hears at time 4, the last arrival.
times = [[1,2,5],[2,3,2]], n = 3, k = 3 returns -1
Node 3 has no outgoing edges, so nodes 1 and 2 never receive the signal.
times = [[2,1,6],[2,3,2],[3,1,1]], n = 3, k = 2 returns 3
Node 1 hears at time 3 through node 3, beating the direct edge's 6.
Constraints
- 1 <= k <= n <= 100
- 1 <= times.length <= 6000
- 1 <= w <= 100
- No two edges share the same ordered pair (u, v).
Hints
When does the last node receive the signal, in terms of shortest paths?
Find the shortest path from k to every node with Dijkstra's algorithm, since every weight is positive.
Push (0, k) on a min-heap. Pop (t, u); if u is settled, skip it, otherwise settle it at t and push (t + w, v) for every edge u to v. Return the largest settled time if all n nodes are settled, else -1.
Drill This: Your Approach First
Approach
Every node hears the signal at its shortest-path distance from k, so the answer is the largest of those distances. With non-negative weights, Dijkstra's algorithm finds them: keep a min-heap of (time, node), pop the earliest, skip it if the node is already settled, and otherwise settle it and push each neighbor at time + w. If fewer than n nodes are settled when the heap empties, return -1; otherwise return the last settled time, which is the largest. O(E log E) time and O(n + E) space.
Time
O(E log E)
Space
O(n + E)
Pitfall
Solutions
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
List<List<int[]>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++) graph.add(new ArrayList<>());
for (int[] t : times) graph.get(t[0]).add(new int[] {t[1], t[2]});
PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
heap.offer(new int[] {0, k});
boolean[] settled = new boolean[n + 1];
int count = 0, last = 0;
while (!heap.isEmpty()) {
int[] top = heap.poll();
int time = top[0], u = top[1];
if (settled[u]) continue;
settled[u] = true;
count++;
last = time;
for (int[] edge : graph.get(u)) {
if (!settled[edge[0]]) heap.offer(new int[] {time + edge[1], edge[0]});
}
}
return count == n ? last : -1;
}
}import heapq
from collections import defaultdict
class Solution:
def networkDelayTime(self, times, n: int, k: int) -> int:
graph = defaultdict(list)
for u, v, w in times:
graph[u].append((v, w))
heap = [(0, k)]
settled = {}
while heap:
time, u = heapq.heappop(heap)
if u in settled:
continue
settled[u] = time
for v, w in graph[u]:
if v not in settled:
heapq.heappush(heap, (time + w, v))
return max(settled.values()) if len(settled) == n else -1