Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 91eb4dc

Browse files
Merge pull request SharingSource#335 from SharingSource/ac_oier
✨update: Modify 2045
2 parents 82cb709 + 8fe122c commit 91eb4dc

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

‎LeetCode/2041-2050/2045. 到达目的地的第二短时间(困难).md‎

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Tag : 「最短路」、「BFS」、「堆优化 Dijkstra」
7878

7979
对「堆优化 Dijkstra」或者「其他最短路算法」不熟悉的同学,可以看前置 🧀 :[【最短路/必背模板】涵盖所有的「存图方式」与「最短路算法(详尽注释)」](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247488007&idx=1&sn=9d0dcfdf475168d26a5a4bd6fcd3505d&chksm=fd9cb918caeb300e1c8844583db5c5318a89e60d8d552747ff8c2256910d32acd9013c93058f&token=211780171&lang=zh_CN#rd)。内容如题,首次接触的话,建议每个模板先敲十遍。
8080

81-
回到本题,与常规的「求最短路」不同,本题需要求得「严格次短路」,我们可以原来的最短路算法基础上($dist1[]$ 数组用于记录最短路)多引入一个 $dist2[]$ 数组,$dist2[x]$ 用于记录从节点 1ドル$ 到节点 $x$ 的严格次短路。
81+
回到本题,与常规的「求最短路」不同,本题需要求得「严格次短路」,我们可以在原来的最短路算法基础上($dist1[]$ 数组用于记录最短路)多引入一个 $dist2[]$ 数组,$dist2[x]$ 用于记录从节点 1ドル$ 到节点 $x$ 的严格次短路。
8282

8383
维护次短路是容易的,基本思路为:
8484

@@ -93,7 +93,7 @@ Tag : 「最短路」、「BFS」、「堆优化 Dijkstra」
9393
* $\left \lfloor \frac{step}{change} \right \rfloor$ 为偶数:当前处于绿灯,动态边权为 0ドル$;
9494
* $\left \lfloor \frac{step}{change} \right \rfloor$ 为奇数:当前处于红灯,需要增加动态边权(等待时间),增加的动态边权为 `change - (step % change)`
9595

96-
最后,为了避免每个样例都 `new` 大数组,我们可以使用 `static` 修饰需要用到的数据,并在执行逻辑前进行重置工作。
96+
最后,为了避免每个样例都 `new` 大数组,我们可以使用 `static` 修饰需要用到的数组,并在执行逻辑前进行重置工作。
9797

9898
代码:
9999
```Java
@@ -208,6 +208,76 @@ class Solution {
208208

209209
---
210210

211+
### AStar 算法
212+
213+
`BFS` 的基础上再进一步,我们可以将问题拓展为「使用 AStar 算法来找第 `K` 短路」(修改代码的 `K` 即可),利用终点的第 $k$ 次出队必然是第 $k$ 短路(注意要求的是严格的第 $k$ 短路)。
214+
215+
代码:
216+
```Java
217+
class Solution {
218+
static int N = 10010, M = 4 * N, INF = 0x3f3f3f3f, K = 2, idx = 0, n = 0;
219+
static int[] he = new int[N], e = new int[M], ne = new int[M];
220+
static int[] dist = new int[N];
221+
void add(int a, int b) {
222+
e[idx] = b;
223+
ne[idx] = he[a];
224+
he[a] = idx;
225+
idx++;
226+
}
227+
void bfs() {
228+
Arrays.fill(dist, INF);
229+
Deque<Integer> d = new ArrayDeque<>();
230+
d.addLast(n);
231+
dist[n] = 0;
232+
while (!d.isEmpty()) {
233+
int x = d.pollFirst(), step = dist[x];
234+
for (int i = he[x]; i != -1; i = ne[i]) {
235+
int j = e[i];
236+
if (dist[j] != INF) continue;
237+
dist[j] = step + 1;
238+
d.addLast(j);
239+
}
240+
}
241+
}
242+
int astar() {
243+
int k = K, min = -1;
244+
PriorityQueue<int[]> q = new PriorityQueue<>((a,b)->a[2]-b[2]);
245+
q.add(new int[]{1, 0, dist[1]});
246+
while (!q.isEmpty()) {
247+
int[] poll = q.poll();
248+
int x = poll[0], step = poll[1];
249+
if (x == n && min != step) {
250+
min = step;
251+
if (--k == 0) return min;
252+
}
253+
for (int i = he[x]; i != -1; i = ne[i]) {
254+
int j = e[i];
255+
q.add(new int[]{j, step + 1, step + 1 + dist[j]});
256+
}
257+
}
258+
return -1; // never
259+
}
260+
public int secondMinimum(int _n, int[][] edges, int time, int change) {
261+
n = _n; idx = 0;
262+
Arrays.fill(he, -1);
263+
for (int[] e : edges) {
264+
int u = e[0], v = e[1];
265+
add(u, v); add(v, u);
266+
}
267+
bfs();
268+
int cnt = astar(), ans = 0;
269+
for (int i = 0; i < cnt; i++) {
270+
int a = ans / change, b = ans % change;
271+
int wait = a % 2 == 0 ? 0 : change - b;
272+
ans += time + wait;
273+
}
274+
return ans;
275+
}
276+
}
277+
```
278+
279+
---
280+
211281
### 最后
212282

213283
这是我们「刷穿 LeetCode」系列文章的第 `No.2045` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /