1. 程式人生 > >[筆記]K短路

[筆記]K短路

一.定義:從起點S出發到達目標T的第K小的路徑
二.樸素演算法
 直接BFS(帶優先佇列),當目標節點T第K次出佇列時,即為所求.
 解釋:BFS第一次搜到T點時,即為最短距離,那麼當第二次搜到呢?不用說,是次短路
 RT. : 次短路   節點(距離)   S:1    T:6
這裡寫圖片描述
出佇列 佇列內元素
1(0)  2(7) 3(9) 6(14)
2(7)  3(9) 6(14) 1(14) 3(17) 4(22)
3(9)  6(11) 6(14) 1(14) 3(17) 1(18) 2(19) 4(20) 4(22)
6(11)   3(13) 6(14) 1(14) 3(17) 1(18) 2(19) 4(20) 5(20) 4(22) 1(25)
3(13)   6(14) 6(15) 1(14) 3(17) 1(18) 2(19) 4(20) 5(20) 4(22) 1(22) 2(23) 4(25) 1(25)
6(14)   end

三.優化演算法—A*演算法
  1)作為BFS的優化,A*是十分強大的.簡單的來說它就是確定了較為準確優先順序的BFS(帶優先佇列).
  較為準確的優先順序—評估函式:f(p)=g(p)+h(p)
  —A*演算法的核心.此函式標準解讀為:評估代價=起點至P點的實際代價(G)+P至S的預計代價(H).在此題中可理解為:評估距離=已走過的距離(G)+P至S的預計距離(H)
  —關於h():令實際代價為h’() ,則:
     1.h()<h’() 會導致估計不準確,從而WA
     2.h()>=h’() h()-h’() 越小,速度越快.大則反之
  2)

結合上述規律,要儘快求出ans,保證演算法速度,就要使h()儘可能與h’()相近. 廢話當然,略微思考就會發現h()’是可以直接預處理出來的: 將圖反向後求一遍單源最短路即可.
  3)步驟:
    1.將圖反向求一遍spfa / dijkstra ,預處理出h()
    2.BFS(A*),記錄出佇列次數,後進行拓展
    3. 若T的出佇列次數等於K,得出ans,終止迴圈
四.注意點
  1.求最短路時邊反向
  2.當S==T時,第一次dis=0時不算在內
  3.注意"判斷到達終點"的位置,必須從優先佇列中取出後判斷