Network Delay Time medium
Problem Statement
You are given a network of n
nodes, labeled from 1
to n
. You are also given times
, a list of travel times as directed edges (u, v, w)
, where u
is the source node, v
is the target node, and w
is the time it takes for a signal to travel from source to target.
Now, we send a signal from a certain node k
. Your task is to find the minimum time it takes for all the n
nodes to receive the signal. If it is impossible, return -1
.
Example 1
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2
Explanation: The graph looks like this:
2 --> 1 (1 unit time)
2 --> 3 (1 unit time)
3 --> 4 (1 unit time)
The minimum time to reach all nodes from node 2 is 2 (2->3->4).
Example 2
Input: times = [[1,2,1]], n = 2, k = 1
Output: 1
Explanation: The graph looks like this:
1 --> 2 (1 unit time)
The minimum time to reach all nodes from node 1 is 1.
Steps
-
Represent the graph: Use an adjacency list to represent the directed graph. The adjacency list will store the destination nodes and the weights of the edges for each source node.
-
Dijkstra's Algorithm: Use Dijkstra's algorithm to find the shortest path from the starting node
k
to all other nodes. Dijkstra's is ideal because it efficiently finds the shortest paths in a graph with non-negative edge weights. -
Distance Array: Initialize a distance array
dist
of sizen+1
(to account for 1-based indexing) withINT_MAX
for all nodes except the starting nodek
, which is initialized to 0. -
Min Heap (Priority Queue): Use a min-heap (priority queue) to efficiently retrieve the node with the smallest distance.
-
Iteration: Iterate until the min-heap is empty. In each iteration:
- Extract the node
u
with the smallest distance from the min-heap. - Iterate through its neighbors.
- If a shorter path to a neighbor
v
is found (dist[u] + weight < dist[v]
), updatedist[v]
and addv
to the min-heap.
- Extract the node
-
Maximum Distance: After Dijkstra's algorithm completes, find the maximum distance among all nodes. This represents the time it takes to reach the furthest node.
-
Check for Unreachable Nodes: If any node's distance remains
INT_MAX
after the algorithm, it means it's unreachable fromk
, and we return-1
.
Explanation
Dijkstra's algorithm systematically explores the graph, always choosing the node with the shortest known distance from the source. The min-heap ensures that we efficiently select the next node to explore. The algorithm guarantees finding the shortest paths from the source node to all other reachable nodes.
Code
#include <iostream>
#include <vector>
#include <limits> // for numeric_limits
#include <queue>
using namespace std;
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
// Adjacency list representation of the graph
vector<vector<pair<int, int>>> graph(n + 1);
for (const auto& time : times) {
graph[time[0]].push_back({time[1], time[2]});
}
// Initialize distances to infinity except for the starting node
vector<int> dist(n + 1, numeric_limits<int>::max());
dist[k] = 0;
// Min-heap (priority queue)
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, k});
while (!pq.empty()) {
int d = pq.top().first;
int u = pq.top().second;
pq.pop();
// If the current distance is greater than the stored distance, skip
if (d > dist[u]) continue;
// Explore neighbors
for (const auto& edge : graph[u]) {
int v = edge.first;
int weight = edge.second;
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
pq.push({dist[v], v});
}
}
}
// Find the maximum distance and check for unreachable nodes
int maxDist = 0;
for (int i = 1; i <= n; ++i) {
if (dist[i] == numeric_limits<int>::max()) return -1; // Unreachable node
maxDist = max(maxDist, dist[i]);
}
return maxDist;
}
int main() {
vector<vector<int>> times1 = {{2, 1, 1}, {2, 3, 1}, {3, 4, 1}};
int n1 = 4, k1 = 2;
cout << "Example 1: " << networkDelayTime(times1, n1, k1) << endl; // Output: 2
vector<vector<int>> times2 = {{1, 2, 1}};
int n2 = 2, k2 = 1;
cout << "Example 2: " << networkDelayTime(times2, n2, k2) << endl; // Output: 1
return 0;
}
Complexity
- Time Complexity: O(E log V), where E is the number of edges and V is the number of vertices (nodes). This is dominated by Dijkstra's algorithm using a min-heap.
- Space Complexity: O(V + E) due to the adjacency list and the distance array. The priority queue also takes space proportional to the number of edges in the worst case.