|
57 | 57 |
|
58 | 58 | ## Solutions
|
59 | 59 |
|
| 60 | +**Solution 1: Dijkstra Algorithm** |
| 61 | + |
| 62 | +First, we construct a graph $g$ based on the given edges, where $g[u]$ represents all neighboring nodes of node $u$ and their corresponding edge weights. |
| 63 | + |
| 64 | +Then, we use Dijkstra's algorithm to find the shortest path from node $s$ to node $d$. However, we need to make some modifications to Dijkstra's algorithm: |
| 65 | + |
| 66 | +- We need to record the shortest path length from each node $u$ to node $d$, but since we can cross at most $k$ edges, we need to record the shortest path length from each node $u$ to node $d$ and the number of edges crossed $t$, i.e., $dist[u][t]$ represents the shortest path length from node $u$ to node $d$ and the number of edges crossed is $t$. |
| 67 | +- We need to use a priority queue to maintain the current shortest path, but since we need to record the number of edges crossed, we need to use a triple $(dis, u, t)$ to represent the current shortest path, where $dis$ represents the current shortest path length, and $u$ and $t$ represent the current node and the number of edges crossed, respectively. |
| 68 | + |
| 69 | +Finally, we only need to return the minimum value in $dist[d][0..k]$. |
| 70 | + |
| 71 | +The time complexity is $O(n^2 \times \log n)$, and the space complexity is $O(n \times k)$, where $n$ represents the number of nodes and $k$ represents the maximum number of edges crossed. |
| 72 | + |
60 | 73 | <!-- tabs:start -->
|
61 | 74 |
|
62 | 75 | ### **Python3**
|
63 | 76 |
|
64 | 77 | ```python
|
65 |
| - |
| 78 | +class Solution: |
| 79 | + def shortestPathWithHops(self, n: int, edges: List[List[int]], s: int, d: int, k: int) -> int: |
| 80 | + g = [[] for _ in range(n)] |
| 81 | + for u, v, w in edges: |
| 82 | + g[u].append((v, w)) |
| 83 | + g[v].append((u, w)) |
| 84 | + dist = [[inf] * (k + 1) for _ in range(n)] |
| 85 | + dist[s][0] = 0 |
| 86 | + pq = [(0, s, 0)] |
| 87 | + while pq: |
| 88 | + dis, u, t = heappop(pq) |
| 89 | + for v, w in g[u]: |
| 90 | + if t + 1 <= k and dist[v][t + 1] > dis: |
| 91 | + dist[v][t + 1] = dis |
| 92 | + heappush(pq, (dis, v, t + 1)) |
| 93 | + if dist[v][t] > dis + w: |
| 94 | + dist[v][t] = dis + w |
| 95 | + heappush(pq, (dis + w, v, t)) |
| 96 | + return int(min(dist[d])) |
66 | 97 | ```
|
67 | 98 |
|
68 | 99 | ### **Java**
|
69 | 100 |
|
70 | 101 | ```java
|
71 |
| - |
| 102 | +class Solution { |
| 103 | + public int shortestPathWithHops(int n, int[][] edges, int s, int d, int k) { |
| 104 | + List<int[]>[] g = new List[n]; |
| 105 | + Arrays.setAll(g, i -> new ArrayList<>()); |
| 106 | + for (int[] e : edges) { |
| 107 | + int u = e[0], v = e[1], w = e[2]; |
| 108 | + g[u].add(new int[] {v, w}); |
| 109 | + g[v].add(new int[] {u, w}); |
| 110 | + } |
| 111 | + PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); |
| 112 | + pq.offer(new int[] {0, s, 0}); |
| 113 | + int[][] dist = new int[n][k + 1]; |
| 114 | + final int inf = 1 << 30; |
| 115 | + for (int[] e : dist) { |
| 116 | + Arrays.fill(e, inf); |
| 117 | + } |
| 118 | + dist[s][0] = 0; |
| 119 | + while (!pq.isEmpty()) { |
| 120 | + int[] p = pq.poll(); |
| 121 | + int dis = p[0], u = p[1], t = p[2]; |
| 122 | + for (int[] e : g[u]) { |
| 123 | + int v = e[0], w = e[1]; |
| 124 | + if (t + 1 <= k && dist[v][t + 1] > dis) { |
| 125 | + dist[v][t + 1] = dis; |
| 126 | + pq.offer(new int[] {dis, v, t + 1}); |
| 127 | + } |
| 128 | + if (dist[v][t] > dis + w) { |
| 129 | + dist[v][t] = dis + w; |
| 130 | + pq.offer(new int[] {dis + w, v, t}); |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | + int ans = inf; |
| 135 | + for (int i = 0; i <= k; ++i) { |
| 136 | + ans = Math.min(ans, dist[d][i]); |
| 137 | + } |
| 138 | + return ans; |
| 139 | + } |
| 140 | +} |
72 | 141 | ```
|
73 | 142 |
|
74 | 143 | ### **C++**
|
75 | 144 |
|
76 | 145 | ```cpp
|
77 |
| - |
| 146 | +class Solution { |
| 147 | +public: |
| 148 | + int shortestPathWithHops(int n, vector<vector<int>>& edges, int s, int d, int k) { |
| 149 | + vector<pair<int, int>> g[n]; |
| 150 | + for (auto& e : edges) { |
| 151 | + int u = e[0], v = e[1], w = e[2]; |
| 152 | + g[u].emplace_back(v, w); |
| 153 | + g[v].emplace_back(u, w); |
| 154 | + } |
| 155 | + priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq; |
| 156 | + pq.emplace(0, s, 0); |
| 157 | + int dist[n][k + 1]; |
| 158 | + memset(dist, 0x3f, sizeof(dist)); |
| 159 | + dist[s][0] = 0; |
| 160 | + while (!pq.empty()) { |
| 161 | + auto [dis, u, t] = pq.top(); |
| 162 | + pq.pop(); |
| 163 | + for (auto [v, w] : g[u]) { |
| 164 | + if (t + 1 <= k && dist[v][t + 1] > dis) { |
| 165 | + dist[v][t + 1] = dis; |
| 166 | + pq.emplace(dis, v, t + 1); |
| 167 | + } |
| 168 | + if (dist[v][t] > dis + w) { |
| 169 | + dist[v][t] = dis + w; |
| 170 | + pq.emplace(dis + w, v, t); |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + return *min_element(dist[d], dist[d] + k + 1); |
| 175 | + } |
| 176 | +}; |
78 | 177 | ```
|
79 | 178 |
|
80 | 179 | ### **Go**
|
81 | 180 |
|
82 | 181 | ```go
|
83 |
| - |
| 182 | +func shortestPathWithHops(n int, edges [][]int, s int, d int, k int) int { |
| 183 | + g := make([][][2]int, n) |
| 184 | + for _, e := range edges { |
| 185 | + u, v, w := e[0], e[1], e[2] |
| 186 | + g[u] = append(g[u], [2]int{v, w}) |
| 187 | + g[v] = append(g[v], [2]int{u, w}) |
| 188 | + } |
| 189 | + pq := hp{{0, s, 0}} |
| 190 | + dist := make([][]int, n) |
| 191 | + for i := range dist { |
| 192 | + dist[i] = make([]int, k+1) |
| 193 | + for j := range dist[i] { |
| 194 | + dist[i][j] = math.MaxInt32 |
| 195 | + } |
| 196 | + } |
| 197 | + dist[s][0] = 0 |
| 198 | + for len(pq) > 0 { |
| 199 | + p := heap.Pop(&pq).(tuple) |
| 200 | + dis, u, t := p.dis, p.u, p.t |
| 201 | + for _, e := range g[u] { |
| 202 | + v, w := e[0], e[1] |
| 203 | + if t+1 <= k && dist[v][t+1] > dis { |
| 204 | + dist[v][t+1] = dis |
| 205 | + heap.Push(&pq, tuple{dis, v, t + 1}) |
| 206 | + } |
| 207 | + if dist[v][t] > dis+w { |
| 208 | + dist[v][t] = dis + w |
| 209 | + heap.Push(&pq, tuple{dis + w, v, t}) |
| 210 | + } |
| 211 | + } |
| 212 | + } |
| 213 | + ans := math.MaxInt32 |
| 214 | + for i := 0; i <= k; i++ { |
| 215 | + ans = min(ans, dist[d][i]) |
| 216 | + } |
| 217 | + return ans |
| 218 | +} |
| 219 | +
|
| 220 | +func min(a, b int) int { |
| 221 | + if a < b { |
| 222 | + return a |
| 223 | + } |
| 224 | + return b |
| 225 | +} |
| 226 | +
|
| 227 | +type tuple struct{ dis, u, t int } |
| 228 | +type hp []tuple |
| 229 | +
|
| 230 | +func (h hp) Len() int { return len(h) } |
| 231 | +func (h hp) Less(i, j int) bool { return h[i].dis < h[j].dis } |
| 232 | +func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } |
| 233 | +func (h *hp) Push(v any) { *h = append(*h, v.(tuple)) } |
| 234 | +func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } |
84 | 235 | ```
|
85 | 236 |
|
86 | 237 | ### **...**
|
|
0 commit comments