LC.P1786[从第一个节点出发到最后一个节点的受限路径数]
方法一:堆优化Dijkstra+动态规划 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 class Solution { private static final int MOD = (int ) 1e9 + 7 ; public int countRestrictedPaths (int n, int [][] edges) { Map<Integer, List<int []>> map = new HashMap <>(); for (int [] e : edges) { int a = e[0 ], b = e[1 ], w = e[2 ]; map.computeIfAbsent(a, k -> new ArrayList <>()).add(new int []{b, w}); map.computeIfAbsent(b, k -> new ArrayList <>()).add(new int []{a, w}); } int [] dist = new int [n + 1 ]; boolean [] visited = new boolean [n + 1 ]; Arrays.fill(dist, Integer.MAX_VALUE); dist[n] = 0 ; PriorityQueue<int []> q = new PriorityQueue <>((a, b) -> a[1 ] - b[1 ]); q.add(new int []{n, 0 }); while (!q.isEmpty()) { int [] cur = q.poll(); int idx = cur[0 ]; if (visited[idx]) continue ; visited[idx] = true ; List<int []> list = map.get(idx); if (list == null ) continue ; for (int [] arr : list) { int i = arr[0 ]; dist[i] = Math.min(dist[i], dist[idx] + arr[1 ]); q.offer(new int []{i, dist[i]}); } } int [][] arr = new int [n][2 ]; for (int i = 0 ; i < n; ++i) arr[i] = new int []{i + 1 , dist[i + 1 ]}; Arrays.sort(arr, (a, b) -> a[1 ] - b[1 ]); int [] f = new int [n + 1 ]; f[n] = 1 ; for (int i = 0 ; i < n; ++i) { int idx = arr[i][0 ], cur = arr[i][1 ]; List<int []> list = map.get(idx); if (list == null ) continue ; for (int [] a : list) { int next = a[0 ]; if (cur > dist[next]) { f[idx] += f[next]; f[idx] %= MOD; } } if (idx == 1 ) break ; } return f[1 ]; } }
时间复杂度:$O(mlogn)$
空间复杂度:$O(m + n)$