1976 Number of Ways to Arrive at Destination

1976 Number of Ways to Arrive at Destination#

Problem#

You are in a city that consists of n intersections numbered from 0 to n - 1 with bi-directional roads between some intersections. The inputs are generated such that you can reach any intersection from any other intersection and that there is at most one road between any two intersections.

You are given an integer n and a 2D integer array roads where roads[i] = [ui, vi, timei] means that there is a road between intersections ui and vi that takes timei minutes to travel. You want to know in how many ways you can travel from intersection 0 to intersection n - 1 in the shortest amount of time.

Return the number of ways you can arrive at your destination in the shortest amount of time. Since the answer may be large, return it modulo 10^9 + 7.

Examples#

Example 1:

Input: n = 7, roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
Output: 4
Explanation: The shortest amount of time it takes to go from intersection 0 to intersection 6 is 7 minutes.
The four ways to get there in 7 minutes are:
- 0 ➝ 6
- 0 ➝ 4 ➝ 6
- 0 ➝ 1 ➝ 2 ➝ 5 ➝ 6
- 0 ➝ 1 ➝ 3 ➝ 5 ➝ 6

Example 2:

Input: n = 2, roads = [[1,0,10]]
Output: 1
Explanation: There is only one way to go from intersection 0 to intersection 1, and it takes 10 minutes.

Constraint#

1 <= n <= 200
n - 1 <= roads.length <= n * (n - 1) / 2
roads[i].length == 3
0 <= ui, vi <= n - 1
1 <= timei <= 109
ui != vi
There is at most one road connecting any two intersections.
You can reach any intersection from any other intersection.

Analysis#

Three methods can be used for solving this shortest weighted path problems:

  • BFS

  • DFS

  • Dijkstra

    • However, Dijkstra’s algorithm is for DAG, how to use it for undirected graph?

      • construct directed graph from undirected graph by treating it as bidirectional graph Dijkstra’s algorithm is too slow for large E, as its time complexity is O(E + VlogV), and E could be as large as \(V^2\).

  • A*, A-star

    • this

Solution#

import heapq 

def countPaths(n, roads):
    # build graph
    graph = {}
    weights = {}
    for i in range(n):
        graph[i] = []
    for u, v, w in roads:
        graph[u].append(v)
        graph[v].append(u)
        weights[(u,v)] = w
        weights[(v,u)] = w
    
    # dijkstra
    # initialize distance table and path
    # we can use count table instead of path table to save memory
    distances = [float("inf") for _ in range(n)]
    distances[0] = 0
    path = [0]
    paths = []

    # initialize a priority queue
    queue = [(distances[0], path)]

    # loop until queue is empty
    while queue:
        # heap pop the smallest distance
        distance, path = heapq.heappop(queue)
        node = path[-1]

        # if we reach the destination, add the path to the path list
        if node == n-1:
            paths.append(path)
            continue
        
        # if the distance is larger than the current distance, skip
        if distance > distances[node]:
            continue
        
        # loop through neighbors
        for neighbor in graph[node]:
            distance_neighbor = distance + weights[(node, neighbor)]
            # if the distance to neighbor is smaller than the current distance, update the distance and add the path to the queue
            if distance_neighbor <= distances[neighbor]:
                distances[neighbor] = distance_neighbor
                heapq.heappush(queue, (distances[neighbor], path+[neighbor]))
            
    return len(paths) % (10**9 + 7)
# test
# 4
n = 7
roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
print(countPaths(n, roads))

# 1
n = 2
roads = [[1,0,10]]
print(countPaths(n, roads))

# 166
n = 12 
roads = [[1,0,2348],[2,1,2852],[2,0,5200],[3,1,12480],[2,3,9628],[4,3,7367],[4,0,22195],[5,4,5668],[1,5,25515],[0,5,27863],[6,5,836],[6,0,28699],[2,6,23499],[6,3,13871],[1,6,26351],[5,7,6229],[2,7,28892],[1,7,31744],[3,7,19264],[6,7,5393],[2,8,31998],[8,7,3106],[3,8,22370],[8,4,15003],[8,6,8499],[8,5,9335],[8,9,5258],[9,2,37256],[3,9,27628],[7,9,8364],[1,9,40108],[9,5,14593],[2,10,45922],[5,10,23259],[9,10,8666],[10,0,51122],[10,3,36294],[10,4,28927],[11,4,25190],[11,9,4929],[11,8,10187],[11,6,18686],[2,11,42185],[11,3,32557],[1,11,45037]]
print(countPaths(n, roads))

# this test is too slow
n = 34
roads = [[1,0,9611],[0,2,13741],[2,1,4130],[2,3,2339],[3,0,16080],[1,4,9725],[0,4,19336],[3,4,3256],[4,2,5595],[5,4,6224],[6,2,1303],[1,6,5433],[7,6,10824],[4,7,6532],[5,7,308],[7,1,16257],[6,8,14961],[8,4,10669],[8,0,30005],[5,8,4445],[8,3,13925],[8,7,4137],[2,8,16264],[9,4,12915],[0,9,32251],[8,9,2246],[10,7,14204],[0,10,40072],[6,10,25028],[10,8,10067],[10,3,23992],[10,2,26331],[10,1,30461],[4,10,20736],[5,10,14512],[9,10,7821],[11,4,3381],[12,4,27123],[9,12,14208],[10,12,6387],[8,12,16454],[12,0,46459],[7,12,20591],[12,5,20899],[2,12,32718],[12,11,23742],[1,12,36848],[6,12,31415],[5,13,25075],[13,10,10563],[3,13,34555],[13,12,4176],[13,8,20630],[13,1,41024],[13,11,27918],[13,7,24767],[4,13,31299],[2,13,36894],[10,14,8784],[12,14,2397],[4,14,29520],[6,14,33812],[9,14,16605],[14,3,32776],[5,14,23296],[14,2,35115],[8,14,18851],[7,14,22988],[10,15,9236],[15,3,33228],[15,0,49308],[15,12,2849],[4,16,41221],[16,8,30552],[10,16,20485],[16,11,37840],[16,6,45513],[16,14,11701],[3,16,44477],[1,16,50946],[16,5,34997],[16,7,34689],[12,16,14098],[16,0,60557],[16,13,9922],[2,16,46816],[16,9,28306],[17,9,36735],[17,3,52906],[16,17,8429],[8,17,38981],[7,17,43118],[6,17,53942],[4,17,49650],[17,14,20130],[17,13,18351],[17,10,28914],[17,11,46269],[1,17,59375],[15,17,19678],[17,12,22527],[15,18,27895],[18,12,30744],[18,11,54486],[18,4,57867],[3,18,61123],[18,16,16646],[13,18,26568],[18,8,47198],[1,18,67592],[17,18,8217],[0,18,77203],[6,18,62159],[18,14,28347],[19,13,32225],[11,19,60143],[5,19,57300],[19,15,33552],[10,19,42788],[6,19,67816],[7,19,56992],[19,18,5657],[19,1,73249],[16,19,22303],[8,19,52855],[17,19,13874],[19,3,66780],[19,9,50609],[19,0,82860],[19,4,63524],[4,20,69122],[18,20,11255],[3,20,72378],[11,20,65741],[14,20,39602],[10,20,48386],[1,20,78847],[20,5,62898],[20,15,39150],[20,19,5598],[16,20,27901],[12,20,41999],[0,20,88458],[8,20,58453],[20,13,37823],[20,7,62590],[9,20,56207],[2,20,74717],[20,17,19472],[17,21,26673],[16,21,35102],[3,21,79579],[21,18,18456],[21,9,63408],[21,20,7201],[2,21,81918],[21,11,72942],[14,22,50771],[22,19,16767],[22,18,22424],[22,15,50319],[22,13,48992],[22,3,83547],[6,22,84583],[22,5,74067],[22,10,59555],[16,22,39070],[22,20,11169],[22,12,53168],[4,22,80291],[22,2,85886],[22,8,69622],[22,21,3968],[22,17,30641],[0,22,99627],[11,22,76910],[22,7,73759],[2,23,87059],[23,6,85756],[5,23,75240],[23,21,5141],[9,23,68549],[14,23,51944],[20,23,12342],[1,23,91189],[8,23,70795],[11,23,78083],[23,13,50165],[23,22,1173],[12,23,54341],[23,3,84720],[23,10,60728],[23,17,31814],[21,24,5622],[14,24,52425],[24,20,12823],[7,24,75413],[24,2,87540],[25,1,101404],[13,25,60380],[25,7,85147],[9,25,78764],[15,25,61707],[19,25,28155],[25,22,11388],[25,17,42029],[25,5,85455],[16,25,50458],[25,4,91679],[25,23,10215],[25,14,62159],[24,25,9734],[25,21,15356],[25,10,70943],[25,20,22557],[3,25,94935],[0,25,111015],[19,26,31787],[14,26,65791],[26,3,98567],[26,15,65339],[26,25,3632],[24,26,13366],[9,26,82396],[18,26,37444],[26,17,45661],[26,1,105036],[22,26,15020],[26,5,89087],[10,26,74575],[26,2,100906],[11,26,91930],[13,26,64012],[26,12,68188],[26,4,95311],[20,26,26189],[0,26,114647],[26,21,18988],[0,27,100248],[21,27,4589],[2,27,86507],[4,27,80912],[27,9,67997],[14,27,51392],[27,15,50940],[27,10,60176],[27,11,77531],[27,13,49613],[0,28,124384],[28,12,77925],[28,27,24136],[28,26,9737],[28,10,84312],[28,13,73749],[28,16,63827],[20,28,35926],[28,23,23584],[29,6,100376],[29,23,14620],[29,17,46434],[29,25,4405],[22,29,15793],[29,15,66112],[5,29,89860],[0,29,115420],[13,29,64785],[29,4,96084],[29,19,32560],[29,21,19761],[29,26,773],[11,29,92703],[9,29,83169],[29,18,38217],[29,10,75348],[7,29,89552],[1,29,105809],[29,20,26962],[29,16,54863],[12,29,68961],[29,2,101679],[29,24,14139],[4,30,111360],[10,30,90624],[30,5,105136],[30,1,121085],[8,30,100691],[28,30,6312],[27,30,30448],[30,24,29415],[30,26,16049],[30,12,84237],[6,30,115652],[30,2,116955],[30,14,81840],[30,20,42238],[30,29,15276],[30,9,98445],[30,3,114616],[30,16,70139],[21,30,35037],[30,25,19681],[30,13,80061],[18,30,53493],[30,11,107979],[30,15,81388],[30,0,130696],[31,16,58739],[31,29,3876],[6,31,104252],[31,2,105555],[31,15,69988],[1,32,117525],[20,32,38678],[7,32,101268],[27,32,26888],[25,32,16121],[29,32,11716],[23,32,26336],[32,14,78280],[31,32,7840],[15,32,77828],[32,5,101576],[11,32,104419],[12,32,80677],[23,33,30143],[18,33,53740],[33,10,90871],[31,33,11647],[33,21,35284],[33,25,19928],[33,32,3807],[33,26,16296]]
print(countPaths(n, roads))
4
1
166
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[1], line 69
     67 n = 34
     68 roads = [[1,0,9611],[0,2,13741],[2,1,4130],[2,3,2339],[3,0,16080],[1,4,9725],[0,4,19336],[3,4,3256],[4,2,5595],[5,4,6224],[6,2,1303],[1,6,5433],[7,6,10824],[4,7,6532],[5,7,308],[7,1,16257],[6,8,14961],[8,4,10669],[8,0,30005],[5,8,4445],[8,3,13925],[8,7,4137],[2,8,16264],[9,4,12915],[0,9,32251],[8,9,2246],[10,7,14204],[0,10,40072],[6,10,25028],[10,8,10067],[10,3,23992],[10,2,26331],[10,1,30461],[4,10,20736],[5,10,14512],[9,10,7821],[11,4,3381],[12,4,27123],[9,12,14208],[10,12,6387],[8,12,16454],[12,0,46459],[7,12,20591],[12,5,20899],[2,12,32718],[12,11,23742],[1,12,36848],[6,12,31415],[5,13,25075],[13,10,10563],[3,13,34555],[13,12,4176],[13,8,20630],[13,1,41024],[13,11,27918],[13,7,24767],[4,13,31299],[2,13,36894],[10,14,8784],[12,14,2397],[4,14,29520],[6,14,33812],[9,14,16605],[14,3,32776],[5,14,23296],[14,2,35115],[8,14,18851],[7,14,22988],[10,15,9236],[15,3,33228],[15,0,49308],[15,12,2849],[4,16,41221],[16,8,30552],[10,16,20485],[16,11,37840],[16,6,45513],[16,14,11701],[3,16,44477],[1,16,50946],[16,5,34997],[16,7,34689],[12,16,14098],[16,0,60557],[16,13,9922],[2,16,46816],[16,9,28306],[17,9,36735],[17,3,52906],[16,17,8429],[8,17,38981],[7,17,43118],[6,17,53942],[4,17,49650],[17,14,20130],[17,13,18351],[17,10,28914],[17,11,46269],[1,17,59375],[15,17,19678],[17,12,22527],[15,18,27895],[18,12,30744],[18,11,54486],[18,4,57867],[3,18,61123],[18,16,16646],[13,18,26568],[18,8,47198],[1,18,67592],[17,18,8217],[0,18,77203],[6,18,62159],[18,14,28347],[19,13,32225],[11,19,60143],[5,19,57300],[19,15,33552],[10,19,42788],[6,19,67816],[7,19,56992],[19,18,5657],[19,1,73249],[16,19,22303],[8,19,52855],[17,19,13874],[19,3,66780],[19,9,50609],[19,0,82860],[19,4,63524],[4,20,69122],[18,20,11255],[3,20,72378],[11,20,65741],[14,20,39602],[10,20,48386],[1,20,78847],[20,5,62898],[20,15,39150],[20,19,5598],[16,20,27901],[12,20,41999],[0,20,88458],[8,20,58453],[20,13,37823],[20,7,62590],[9,20,56207],[2,20,74717],[20,17,19472],[17,21,26673],[16,21,35102],[3,21,79579],[21,18,18456],[21,9,63408],[21,20,7201],[2,21,81918],[21,11,72942],[14,22,50771],[22,19,16767],[22,18,22424],[22,15,50319],[22,13,48992],[22,3,83547],[6,22,84583],[22,5,74067],[22,10,59555],[16,22,39070],[22,20,11169],[22,12,53168],[4,22,80291],[22,2,85886],[22,8,69622],[22,21,3968],[22,17,30641],[0,22,99627],[11,22,76910],[22,7,73759],[2,23,87059],[23,6,85756],[5,23,75240],[23,21,5141],[9,23,68549],[14,23,51944],[20,23,12342],[1,23,91189],[8,23,70795],[11,23,78083],[23,13,50165],[23,22,1173],[12,23,54341],[23,3,84720],[23,10,60728],[23,17,31814],[21,24,5622],[14,24,52425],[24,20,12823],[7,24,75413],[24,2,87540],[25,1,101404],[13,25,60380],[25,7,85147],[9,25,78764],[15,25,61707],[19,25,28155],[25,22,11388],[25,17,42029],[25,5,85455],[16,25,50458],[25,4,91679],[25,23,10215],[25,14,62159],[24,25,9734],[25,21,15356],[25,10,70943],[25,20,22557],[3,25,94935],[0,25,111015],[19,26,31787],[14,26,65791],[26,3,98567],[26,15,65339],[26,25,3632],[24,26,13366],[9,26,82396],[18,26,37444],[26,17,45661],[26,1,105036],[22,26,15020],[26,5,89087],[10,26,74575],[26,2,100906],[11,26,91930],[13,26,64012],[26,12,68188],[26,4,95311],[20,26,26189],[0,26,114647],[26,21,18988],[0,27,100248],[21,27,4589],[2,27,86507],[4,27,80912],[27,9,67997],[14,27,51392],[27,15,50940],[27,10,60176],[27,11,77531],[27,13,49613],[0,28,124384],[28,12,77925],[28,27,24136],[28,26,9737],[28,10,84312],[28,13,73749],[28,16,63827],[20,28,35926],[28,23,23584],[29,6,100376],[29,23,14620],[29,17,46434],[29,25,4405],[22,29,15793],[29,15,66112],[5,29,89860],[0,29,115420],[13,29,64785],[29,4,96084],[29,19,32560],[29,21,19761],[29,26,773],[11,29,92703],[9,29,83169],[29,18,38217],[29,10,75348],[7,29,89552],[1,29,105809],[29,20,26962],[29,16,54863],[12,29,68961],[29,2,101679],[29,24,14139],[4,30,111360],[10,30,90624],[30,5,105136],[30,1,121085],[8,30,100691],[28,30,6312],[27,30,30448],[30,24,29415],[30,26,16049],[30,12,84237],[6,30,115652],[30,2,116955],[30,14,81840],[30,20,42238],[30,29,15276],[30,9,98445],[30,3,114616],[30,16,70139],[21,30,35037],[30,25,19681],[30,13,80061],[18,30,53493],[30,11,107979],[30,15,81388],[30,0,130696],[31,16,58739],[31,29,3876],[6,31,104252],[31,2,105555],[31,15,69988],[1,32,117525],[20,32,38678],[7,32,101268],[27,32,26888],[25,32,16121],[29,32,11716],[23,32,26336],[32,14,78280],[31,32,7840],[15,32,77828],[32,5,101576],[11,32,104419],[12,32,80677],[23,33,30143],[18,33,53740],[33,10,90871],[31,33,11647],[33,21,35284],[33,25,19928],[33,32,3807],[33,26,16296]]
---> 69 print(countPaths(n, roads))

Cell In[1], line 29, in countPaths(n, roads)
     26 # loop until queue is empty
     27 while queue:
     28     # heap pop the smallest distance
---> 29     distance, path = heapq.heappop(queue)
     30     node = path[-1]
     32     # if we reach the destination, add the path to the path list

KeyboardInterrupt: 
import heapq

def countPaths(n, roads):
    # build graph
    graph = {}
    weights = {}
    for i in range(n):
        graph[i] = []
    for u, v, w in roads:
        graph[u].append(v)
        graph[v].append(u)
        weights[(u,v)] = w
        weights[(v,u)] = w
    
    # A*
    distances = [float("inf") for _ in range(n)]
    distances[0] = 0
    heuristics = [float("inf") for _ in range(n)]
    heuristics[0] = 0
    path = [0]
    paths = []

    queue = [(heuristics[0], path)]
    while queue:
        distance, path = heapq.heappop(queue)
        node = path[-1]

        if node == n-1:
            paths.append(path)
            # this continue is important, as when we reach the destination, we don't want to continue to explore the neighbors
            continue

        for neighbor in graph[node]:
            distance_neighbor = distances[node] + weights[(node, neighbor)]
            if distance_neighbor <= distances[neighbor]:
                distances[neighbor] = distance_neighbor
                heuristics[neighbor] = distance_neighbor + abs(n-1 - neighbor) # Using Manhattan distance as heuristic
                heapq.heappush(queue, (heuristics[neighbor], path+[neighbor]))
            
    return len(paths) % (10**9 + 7)

# test
# 4
n = 7
roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
print(countPaths(n, roads))

# 1
n = 2
roads = [[1,0,10]]
print(countPaths(n, roads))

# 166
n = 12 
roads = [[1,0,2348],[2,1,2852],[2,0,5200],[3,1,12480],[2,3,9628],[4,3,7367],[4,0,22195],[5,4,5668],[1,5,25515],[0,5,27863],[6,5,836],[6,0,28699],[2,6,23499],[6,3,13871],[1,6,26351],[5,7,6229],[2,7,28892],[1,7,31744],[3,7,19264],[6,7,5393],[2,8,31998],[8,7,3106],[3,8,22370],[8,4,15003],[8,6,8499],[8,5,9335],[8,9,5258],[9,2,37256],[3,9,27628],[7,9,8364],[1,9,40108],[9,5,14593],[2,10,45922],[5,10,23259],[9,10,8666],[10,0,51122],[10,3,36294],[10,4,28927],[11,4,25190],[11,9,4929],[11,8,10187],[11,6,18686],[2,11,42185],[11,3,32557],[1,11,45037]]
print(countPaths(n, roads))

# this test is too slow
n = 34
roads = [[1,0,9611],[0,2,13741],[2,1,4130],[2,3,2339],[3,0,16080],[1,4,9725],[0,4,19336],[3,4,3256],[4,2,5595],[5,4,6224],[6,2,1303],[1,6,5433],[7,6,10824],[4,7,6532],[5,7,308],[7,1,16257],[6,8,14961],[8,4,10669],[8,0,30005],[5,8,4445],[8,3,13925],[8,7,4137],[2,8,16264],[9,4,12915],[0,9,32251],[8,9,2246],[10,7,14204],[0,10,40072],[6,10,25028],[10,8,10067],[10,3,23992],[10,2,26331],[10,1,30461],[4,10,20736],[5,10,14512],[9,10,7821],[11,4,3381],[12,4,27123],[9,12,14208],[10,12,6387],[8,12,16454],[12,0,46459],[7,12,20591],[12,5,20899],[2,12,32718],[12,11,23742],[1,12,36848],[6,12,31415],[5,13,25075],[13,10,10563],[3,13,34555],[13,12,4176],[13,8,20630],[13,1,41024],[13,11,27918],[13,7,24767],[4,13,31299],[2,13,36894],[10,14,8784],[12,14,2397],[4,14,29520],[6,14,33812],[9,14,16605],[14,3,32776],[5,14,23296],[14,2,35115],[8,14,18851],[7,14,22988],[10,15,9236],[15,3,33228],[15,0,49308],[15,12,2849],[4,16,41221],[16,8,30552],[10,16,20485],[16,11,37840],[16,6,45513],[16,14,11701],[3,16,44477],[1,16,50946],[16,5,34997],[16,7,34689],[12,16,14098],[16,0,60557],[16,13,9922],[2,16,46816],[16,9,28306],[17,9,36735],[17,3,52906],[16,17,8429],[8,17,38981],[7,17,43118],[6,17,53942],[4,17,49650],[17,14,20130],[17,13,18351],[17,10,28914],[17,11,46269],[1,17,59375],[15,17,19678],[17,12,22527],[15,18,27895],[18,12,30744],[18,11,54486],[18,4,57867],[3,18,61123],[18,16,16646],[13,18,26568],[18,8,47198],[1,18,67592],[17,18,8217],[0,18,77203],[6,18,62159],[18,14,28347],[19,13,32225],[11,19,60143],[5,19,57300],[19,15,33552],[10,19,42788],[6,19,67816],[7,19,56992],[19,18,5657],[19,1,73249],[16,19,22303],[8,19,52855],[17,19,13874],[19,3,66780],[19,9,50609],[19,0,82860],[19,4,63524],[4,20,69122],[18,20,11255],[3,20,72378],[11,20,65741],[14,20,39602],[10,20,48386],[1,20,78847],[20,5,62898],[20,15,39150],[20,19,5598],[16,20,27901],[12,20,41999],[0,20,88458],[8,20,58453],[20,13,37823],[20,7,62590],[9,20,56207],[2,20,74717],[20,17,19472],[17,21,26673],[16,21,35102],[3,21,79579],[21,18,18456],[21,9,63408],[21,20,7201],[2,21,81918],[21,11,72942],[14,22,50771],[22,19,16767],[22,18,22424],[22,15,50319],[22,13,48992],[22,3,83547],[6,22,84583],[22,5,74067],[22,10,59555],[16,22,39070],[22,20,11169],[22,12,53168],[4,22,80291],[22,2,85886],[22,8,69622],[22,21,3968],[22,17,30641],[0,22,99627],[11,22,76910],[22,7,73759],[2,23,87059],[23,6,85756],[5,23,75240],[23,21,5141],[9,23,68549],[14,23,51944],[20,23,12342],[1,23,91189],[8,23,70795],[11,23,78083],[23,13,50165],[23,22,1173],[12,23,54341],[23,3,84720],[23,10,60728],[23,17,31814],[21,24,5622],[14,24,52425],[24,20,12823],[7,24,75413],[24,2,87540],[25,1,101404],[13,25,60380],[25,7,85147],[9,25,78764],[15,25,61707],[19,25,28155],[25,22,11388],[25,17,42029],[25,5,85455],[16,25,50458],[25,4,91679],[25,23,10215],[25,14,62159],[24,25,9734],[25,21,15356],[25,10,70943],[25,20,22557],[3,25,94935],[0,25,111015],[19,26,31787],[14,26,65791],[26,3,98567],[26,15,65339],[26,25,3632],[24,26,13366],[9,26,82396],[18,26,37444],[26,17,45661],[26,1,105036],[22,26,15020],[26,5,89087],[10,26,74575],[26,2,100906],[11,26,91930],[13,26,64012],[26,12,68188],[26,4,95311],[20,26,26189],[0,26,114647],[26,21,18988],[0,27,100248],[21,27,4589],[2,27,86507],[4,27,80912],[27,9,67997],[14,27,51392],[27,15,50940],[27,10,60176],[27,11,77531],[27,13,49613],[0,28,124384],[28,12,77925],[28,27,24136],[28,26,9737],[28,10,84312],[28,13,73749],[28,16,63827],[20,28,35926],[28,23,23584],[29,6,100376],[29,23,14620],[29,17,46434],[29,25,4405],[22,29,15793],[29,15,66112],[5,29,89860],[0,29,115420],[13,29,64785],[29,4,96084],[29,19,32560],[29,21,19761],[29,26,773],[11,29,92703],[9,29,83169],[29,18,38217],[29,10,75348],[7,29,89552],[1,29,105809],[29,20,26962],[29,16,54863],[12,29,68961],[29,2,101679],[29,24,14139],[4,30,111360],[10,30,90624],[30,5,105136],[30,1,121085],[8,30,100691],[28,30,6312],[27,30,30448],[30,24,29415],[30,26,16049],[30,12,84237],[6,30,115652],[30,2,116955],[30,14,81840],[30,20,42238],[30,29,15276],[30,9,98445],[30,3,114616],[30,16,70139],[21,30,35037],[30,25,19681],[30,13,80061],[18,30,53493],[30,11,107979],[30,15,81388],[30,0,130696],[31,16,58739],[31,29,3876],[6,31,104252],[31,2,105555],[31,15,69988],[1,32,117525],[20,32,38678],[7,32,101268],[27,32,26888],[25,32,16121],[29,32,11716],[23,32,26336],[32,14,78280],[31,32,7840],[15,32,77828],[32,5,101576],[11,32,104419],[12,32,80677],[23,33,30143],[18,33,53740],[33,10,90871],[31,33,11647],[33,21,35284],[33,25,19928],[33,32,3807],[33,26,16296]]
print(countPaths(n, roads))
4
1
166
6347247
# This is from https://leetcode.com/problems/number-of-ways-to-arrive-at-destination/solutions/1417576/c-python-dijkstra-clean-concise/
from collections import defaultdict
from heapq import heappush, heappop
import math 

def countPaths(n, roads):
        graph = defaultdict(list)
        for u, v, time in roads:
            graph[u].append([v, time])
            graph[v].append([u, time])

        def dijkstra(src):
            dist = [math.inf] * n
            ways = [0] * n
            minHeap = [(0, src)]  # dist, src
            dist[src] = 0
            ways[src] = 1
            while minHeap:
                d, u = heappop(minHeap)
                if dist[u] < d: continue  # Skip if `d` is not updated to latest version!
                for v, time in graph[u]:
                    if dist[v] > d + time:
                        dist[v] = d + time
                        ways[v] = ways[u]
                        heappush(minHeap, (dist[v], v))
                    elif dist[v] == d + time:
                        ways[v] = (ways[v] + ways[u]) % 1_000_000_007
            return ways[n - 1]

        return dijkstra(0)

# test
# 4
n = 7
roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
print(countPaths(n, roads))

# 1
n = 2
roads = [[1,0,10]]
print(countPaths(n, roads))

# 166
n = 12 
roads = [[1,0,2348],[2,1,2852],[2,0,5200],[3,1,12480],[2,3,9628],[4,3,7367],[4,0,22195],[5,4,5668],[1,5,25515],[0,5,27863],[6,5,836],[6,0,28699],[2,6,23499],[6,3,13871],[1,6,26351],[5,7,6229],[2,7,28892],[1,7,31744],[3,7,19264],[6,7,5393],[2,8,31998],[8,7,3106],[3,8,22370],[8,4,15003],[8,6,8499],[8,5,9335],[8,9,5258],[9,2,37256],[3,9,27628],[7,9,8364],[1,9,40108],[9,5,14593],[2,10,45922],[5,10,23259],[9,10,8666],[10,0,51122],[10,3,36294],[10,4,28927],[11,4,25190],[11,9,4929],[11,8,10187],[11,6,18686],[2,11,42185],[11,3,32557],[1,11,45037]]
print(countPaths(n, roads))

#
n = 34
roads = [[1,0,9611],[0,2,13741],[2,1,4130],[2,3,2339],[3,0,16080],[1,4,9725],[0,4,19336],[3,4,3256],[4,2,5595],[5,4,6224],[6,2,1303],[1,6,5433],[7,6,10824],[4,7,6532],[5,7,308],[7,1,16257],[6,8,14961],[8,4,10669],[8,0,30005],[5,8,4445],[8,3,13925],[8,7,4137],[2,8,16264],[9,4,12915],[0,9,32251],[8,9,2246],[10,7,14204],[0,10,40072],[6,10,25028],[10,8,10067],[10,3,23992],[10,2,26331],[10,1,30461],[4,10,20736],[5,10,14512],[9,10,7821],[11,4,3381],[12,4,27123],[9,12,14208],[10,12,6387],[8,12,16454],[12,0,46459],[7,12,20591],[12,5,20899],[2,12,32718],[12,11,23742],[1,12,36848],[6,12,31415],[5,13,25075],[13,10,10563],[3,13,34555],[13,12,4176],[13,8,20630],[13,1,41024],[13,11,27918],[13,7,24767],[4,13,31299],[2,13,36894],[10,14,8784],[12,14,2397],[4,14,29520],[6,14,33812],[9,14,16605],[14,3,32776],[5,14,23296],[14,2,35115],[8,14,18851],[7,14,22988],[10,15,9236],[15,3,33228],[15,0,49308],[15,12,2849],[4,16,41221],[16,8,30552],[10,16,20485],[16,11,37840],[16,6,45513],[16,14,11701],[3,16,44477],[1,16,50946],[16,5,34997],[16,7,34689],[12,16,14098],[16,0,60557],[16,13,9922],[2,16,46816],[16,9,28306],[17,9,36735],[17,3,52906],[16,17,8429],[8,17,38981],[7,17,43118],[6,17,53942],[4,17,49650],[17,14,20130],[17,13,18351],[17,10,28914],[17,11,46269],[1,17,59375],[15,17,19678],[17,12,22527],[15,18,27895],[18,12,30744],[18,11,54486],[18,4,57867],[3,18,61123],[18,16,16646],[13,18,26568],[18,8,47198],[1,18,67592],[17,18,8217],[0,18,77203],[6,18,62159],[18,14,28347],[19,13,32225],[11,19,60143],[5,19,57300],[19,15,33552],[10,19,42788],[6,19,67816],[7,19,56992],[19,18,5657],[19,1,73249],[16,19,22303],[8,19,52855],[17,19,13874],[19,3,66780],[19,9,50609],[19,0,82860],[19,4,63524],[4,20,69122],[18,20,11255],[3,20,72378],[11,20,65741],[14,20,39602],[10,20,48386],[1,20,78847],[20,5,62898],[20,15,39150],[20,19,5598],[16,20,27901],[12,20,41999],[0,20,88458],[8,20,58453],[20,13,37823],[20,7,62590],[9,20,56207],[2,20,74717],[20,17,19472],[17,21,26673],[16,21,35102],[3,21,79579],[21,18,18456],[21,9,63408],[21,20,7201],[2,21,81918],[21,11,72942],[14,22,50771],[22,19,16767],[22,18,22424],[22,15,50319],[22,13,48992],[22,3,83547],[6,22,84583],[22,5,74067],[22,10,59555],[16,22,39070],[22,20,11169],[22,12,53168],[4,22,80291],[22,2,85886],[22,8,69622],[22,21,3968],[22,17,30641],[0,22,99627],[11,22,76910],[22,7,73759],[2,23,87059],[23,6,85756],[5,23,75240],[23,21,5141],[9,23,68549],[14,23,51944],[20,23,12342],[1,23,91189],[8,23,70795],[11,23,78083],[23,13,50165],[23,22,1173],[12,23,54341],[23,3,84720],[23,10,60728],[23,17,31814],[21,24,5622],[14,24,52425],[24,20,12823],[7,24,75413],[24,2,87540],[25,1,101404],[13,25,60380],[25,7,85147],[9,25,78764],[15,25,61707],[19,25,28155],[25,22,11388],[25,17,42029],[25,5,85455],[16,25,50458],[25,4,91679],[25,23,10215],[25,14,62159],[24,25,9734],[25,21,15356],[25,10,70943],[25,20,22557],[3,25,94935],[0,25,111015],[19,26,31787],[14,26,65791],[26,3,98567],[26,15,65339],[26,25,3632],[24,26,13366],[9,26,82396],[18,26,37444],[26,17,45661],[26,1,105036],[22,26,15020],[26,5,89087],[10,26,74575],[26,2,100906],[11,26,91930],[13,26,64012],[26,12,68188],[26,4,95311],[20,26,26189],[0,26,114647],[26,21,18988],[0,27,100248],[21,27,4589],[2,27,86507],[4,27,80912],[27,9,67997],[14,27,51392],[27,15,50940],[27,10,60176],[27,11,77531],[27,13,49613],[0,28,124384],[28,12,77925],[28,27,24136],[28,26,9737],[28,10,84312],[28,13,73749],[28,16,63827],[20,28,35926],[28,23,23584],[29,6,100376],[29,23,14620],[29,17,46434],[29,25,4405],[22,29,15793],[29,15,66112],[5,29,89860],[0,29,115420],[13,29,64785],[29,4,96084],[29,19,32560],[29,21,19761],[29,26,773],[11,29,92703],[9,29,83169],[29,18,38217],[29,10,75348],[7,29,89552],[1,29,105809],[29,20,26962],[29,16,54863],[12,29,68961],[29,2,101679],[29,24,14139],[4,30,111360],[10,30,90624],[30,5,105136],[30,1,121085],[8,30,100691],[28,30,6312],[27,30,30448],[30,24,29415],[30,26,16049],[30,12,84237],[6,30,115652],[30,2,116955],[30,14,81840],[30,20,42238],[30,29,15276],[30,9,98445],[30,3,114616],[30,16,70139],[21,30,35037],[30,25,19681],[30,13,80061],[18,30,53493],[30,11,107979],[30,15,81388],[30,0,130696],[31,16,58739],[31,29,3876],[6,31,104252],[31,2,105555],[31,15,69988],[1,32,117525],[20,32,38678],[7,32,101268],[27,32,26888],[25,32,16121],[29,32,11716],[23,32,26336],[32,14,78280],[31,32,7840],[15,32,77828],[32,5,101576],[11,32,104419],[12,32,80677],[23,33,30143],[18,33,53740],[33,10,90871],[31,33,11647],[33,21,35284],[33,25,19928],[33,32,3807],[33,26,16296]]
print(countPaths(n, roads))
4
1
166
6347247