Skip to content

Commit 0416ed4

Browse files
authored
Create reachable-nodes-in-subdivided-graph.py
1 parent 3cf18f1 commit 0416ed4

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Time: O((|E| + |V|) * log|V|) = O(|E| * log|V|),
2+
# if we can further to use Fibonacci heap, it would be O(|E| + |V| * log|V|)
3+
# Space: O(|E| + |V|) = O(|E|)
4+
5+
# Starting with an undirected graph (the "original graph")
6+
# with nodes from 0 to N-1, subdivisions are made to some of the edges.
7+
# The graph is given as follows: edges[k] is a list of integer pairs
8+
# (i, j, n) such that (i, j) is an edge of the original graph,
9+
#
10+
# and n is the total number of new nodes on that edge.
11+
#
12+
# Then, the edge (i, j) is deleted from the original graph,
13+
# n new nodes (x_1, x_2, ..., x_n) are added to the original graph,
14+
#
15+
# and n+1 new edges (i, x_1), (x_1, x_2), (x_2, x_3), ..., (x_{n-1}, x_n), (x_n, j)
16+
# are added to the original graph.
17+
#
18+
# Now, you start at node 0 from the original graph, and in each move,
19+
# you travel along one edge.
20+
#
21+
# Return how many nodes you can reach in at most M moves.
22+
#
23+
# Example 1:
24+
#
25+
# Input: edges = [[0,1,10],[0,2,1],[1,2,2]], M = 6, N = 3
26+
# Output: 13
27+
# Explanation:
28+
# The nodes that are reachable in the final graph after M = 6 moves are indicated below.
29+
#
30+
# Example 2:
31+
#
32+
# Input: edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], M = 10, N = 4
33+
# Output: 23
34+
#
35+
# Note:
36+
# - 0 <= edges.length <= 10000
37+
# - 0 <= edges[i][0] < edges[i][1] < N
38+
# - There does not exist any i != j for which
39+
# edges[i][0] == edges[j][0] and edges[i][1] == edges[j][1].
40+
# - The original graph has no parallel edges.
41+
# - 0 <= edges[i][2] <= 10000
42+
# - 0 <= M <= 10^9
43+
# - 1 <= N <= 3000
44+
45+
import collections
46+
47+
class Solution(object):
48+
def reachableNodes(self, edges, M, N):
49+
"""
50+
:type edges: List[List[int]]
51+
:type M: int
52+
:type N: int
53+
:rtype: int
54+
"""
55+
graph = collections.defaultdict(dict)
56+
for u, v, w in edges:
57+
graph[u][v] = graph[v][u] = w
58+
59+
min_heap = [(0, 0)]
60+
best = collections.defaultdict(lambda: float("inf"))
61+
best[0] = 0
62+
count = collections.defaultdict(lambda: collections.defaultdict(int))
63+
result = 0
64+
while min_heap:
65+
curr_total, node = heapq.heappop(min_heap) # O(|V|*log|V|) in total
66+
if best[node] < curr_total:
67+
continue
68+
result += 1
69+
for nei, weight in graph[node].iteritems():
70+
count[node][nei] = min(weight,
71+
M-curr_total)
72+
next_total = curr_total+weight+1
73+
if next_total <= M and next_total < best[nei]:
74+
heapq.heappush(min_heap, (next_total, nei)) # binary heap O(|E|*log|V|) in total
75+
# Fibonacci heap O(|E|) in total
76+
best[nei] = next_total
77+
for u, v, w in edges:
78+
result += min(w, count[u][v]+count[v][u])
79+
return result

0 commit comments

Comments
 (0)