@@ -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