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 times[i] = (ui, vi, wi), where ui is the source node, vi is the target node, and wi is the time it takes for a signal to travel from source to target.
We will send a signal from a given node k. Return the minimum time it takes for all thennodes to receive the signal. If it is impossible for all the n nodes to receive the signal, return -1.
Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2
Example 2:
Input: times = [[1,2,1]], n = 2, k = 1
Output: 1
Example 3:
Input: times = [[1,2,1]], n = 2, k = 2
Output: -1
Constraints:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
All the pairs (ui, vi) are unique. (i.e., no multiple edges.)
Solutions
Solution 1: Naive Dijkstra Algorithm
We define \(\textit{g}[u][v]\) to represent the edge weight from node \(u\) to node \(v\). If there is no edge between node \(u\) and node \(v\), then \(\textit{g}[u][v] = +\infty\).
We maintain an array \(\textit{dist}\), where \(\textit{dist}[i]\) represents the shortest path length from node \(k\) to node \(i\). Initially, we set all \(\textit{dist}[i]\) to \(+\infty\), except for \(\textit{dist}[k - 1] = 0\). We define an array \(\textit{vis}\), where \(\textit{vis}[i]\) indicates whether node \(i\) has been visited. Initially, we set all \(\textit{vis}[i]\) to \(\text{false}\).
Each time, we find the unvisited node \(t\) with the smallest distance, and then perform relaxation operations centered on node \(t\). For each node \(j\), if \(\textit{dist}[j] > \textit{dist}[t] + \textit{g}[t][j]\), we update \(\textit{dist}[j] = \textit{dist}[t] + \textit{g}[t][j]\).
Finally, we return the maximum value in \(\textit{dist}\) as the answer. If the answer is \(+\infty\), it means there are unreachable nodes, and we return \(-1\).
The time complexity is \(O(n^2 + m)\), and the space complexity is \(O(n^2)\). Here, \(n\) and \(m\) are the number of nodes and edges, respectively.
We can use a priority queue (heap) to optimize the naive Dijkstra algorithm.
We define \(\textit{g}[u]\) to represent all adjacent edges of node \(u\), and \(\textit{dist}[u]\) to represent the shortest path length from node \(k\) to node \(u\). Initially, we set all \(\textit{dist}[u]\) to \(+\infty\), except for \(\textit{dist}[k - 1] = 0\).
We define a priority queue \(\textit{pq}\), where each element is \((\textit{d}, u)\), representing the distance \(\textit{d}\) from node \(u\) to node \(k\). Each time, we take out the node \((\textit{d}, u)\) with the smallest distance from \(\textit{pq}\). If $\textit{d} > \(\textit{dist}[u]\), we skip this node. Otherwise, we traverse all adjacent edges of node \(u\). For each adjacent edge \((v, w)\), if \(\textit{dist}[v] > \textit{dist}[u] + w\), we update \(\textit{dist}[v] = \textit{dist}[u] + w\) and add \((\textit{dist}[v], v)\) to \(\textit{pq}\).
Finally, we return the maximum value in \(\textit{dist}\) as the answer. If the answer is \(+\infty\), it means there are unreachable nodes, and we return \(-1\).
The time complexity is \(O(m \times \log m + n)\), and the space complexity is \(O(n + m)\). Here, \(n\) and \(m\) are the number of nodes and edges, respectively.