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 time it takes for all the n nodes to receive the signal. If it is impossible for all the n nodes to receive the signal, return -1.
Objective: Return the time it takes for all the n nodes to receive the signal. In other words, return the longest time to reach a node from the source node.
Constraints:
1. 1 <= k <= n <= 100
2. 1 <= times.length <= 6000
3. times[i].length == 3
4. 1 <= ui, vi <= n
5. ui != vi
6. 0 <= wi <= 100
7. All the pairs (ui, vi) are unique. (i.e., no multiple edges.)
Edge Cases:
1. When there is a unreachable node
2. When there is a cycle in the graph
Few things to keep in mind:
1. The graph cannot be empty
2. There are unreachable nodes
Logic behind this decision:
Bellman-Ford Algorithm finds the shortest path to all the nodes from the source node. All the conditions were met for me to use the Bellman-Ford Algorithm:
How it works:
1. We will initialize the distances list with positive infinite float value.
2. We will loop through all the edges to update the shortest path to reach certain nodes. If distances[u] > distance[v] + weight, the pre-existing distance distances[u] will be replaced. This is called the relaxation.
3. We will go through the relaxation process n-1 times.
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
distances = [float("inf")] * (n)
distances[k-1] = 0
for _ in range(n-1):
for u,v,w in times:
if distances[u-1] != float("inf") and distances[u-1] + w < distances[v-1]:
distances[v-1] = distances[u-1] + w
if float("inf") in distances:
return -1
else:
return max(distances)
Limitations:
Logic behind this decision:
We can use Dijkstra's SP Algorithm until when we get the distance to all of the nodes. Since all the graphs are non-negative, the algorithm should not have any problem.
How is works:
1. We will initialize the distances list with positive infinite float value.
2. We will convert the times list as a graph dictionary through using the listToDict function.
3. We will iterate through nodes in nodes_to_visit starting from the start node.
def listToDict(self, times):
times_dict = defaultdict(list)
for edge in times:
u,v,w = edge
times_dict[u].append((w,v))
return times_dict
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
distances = [float("inf")] * (n)
# O(E)
graph_dict = self.listToDict(times)
nodes_to_visit = [(0,k)]
while nodes_to_visit:
w, u = heapq.heappop(nodes_to_visit)
if distances[u-1] > w:
distances[u-1] = w
for neighbor in graph_dict[u]:
w2, v = neighbor
if distances[v-1] == float("inf"):
heapq.heappush(nodes_to_visit, (w+w2, v))
if float("inf") in distances:
return -1
else:
return max(distances)
LeetCode Question #743