A星 求第K短路径 POJ 2449

解题背景:求第K短路径也有好几种算法,在我的第一篇关于A星的文章有。主要是A*在Dijkstra算法上的进行BFS,相对来说较为容易理解,所以先搞它吧。

                  而POJ 2449 是我的第一篇A星 呵呵

 

思维拓展:【1】,在网上找来较为经典的解说,就如实奉上:

【算法】
本题有一种最朴素的办法:直接广度优先搜索,一开始路径(s, 0)(这里设路径(i, l)表示从s到i的一条长度为l的路径)入队。然后,每次取队中长度最短的路径,该路径(i, l)出队,可以证明,若这是终点为i的路径第x次出队,该路径一定是图中从s到i的第x短路(若x>K则该路径已无用,舍弃)。然后从点i扩展,将扩展到的路径全部入队。这样直到终点为t的路径第K次出队即可。
该算法容易实现(借助priority_queue),但时间复杂度可能达到O(MK),需要优化。
优化:容易发现该算法其实有A*的思想,或者说,该算法其实是所有结点的估价函数h()值均为0的A*算法。为了优化此题,需要将h()值改大。显然,h(i)值可以设为从i到t的最短路径长度(容易证明它是一致的),然后g(i)=目前结点代表的路径长度,f(i)=g(i)+h(i),然后A*即可。
注意:更改路径条数应该在出队时更改,而不能在入队时更改,因为可能在该路径出队之前会有新的比它更短的路径入队。

1.用dijkstra逆向计算出所有点到t的最短距离dis[i]
2.建立估价函数 f(i)= g(i)+h(i)
  其中g(i)为从s到i的实际距离,h(i)为从i到t的最短路dis[i]
3.使用上述估计函数用A*算法从s点出发BFS全图,用visited[i]表示点i的出队次数。
  当visited[i]=k时,即找到从s到t的k短路为f(i)
  其间若visited[i]>k则放弃该点

4.注意:若s==t,需 k+1;

 

 

 

你可能感兴趣的:(优化,算法,扩展)