最短路演算法總結

2022-05-16 10:44:54 字數 2057 閱讀 6560

顧名思義就是尋找乙個源點到其它的點的最短路,暴力的dfs或者bfs就不說了,下面講講幾種單源最短路的演算法。

這個演算法的實質就是利用bfs,我們先將源點到源點的距離設定為0,到其它的距離設定為無窮大(一般0x7fffffff),然後將源點加入佇列,用隊首的點去bfs,更新它能到達且能更新的的點,然後將未進入佇列的點加入佇列以備後續更新使用,然後將已經出隊的點標記消掉,不斷這樣進行這個操作(這個也就是鬆弛操作),最後無法再更新任何乙個點時,隊列為空,最短路也就找完了,理論複雜度為o(

kn)'>o(k

n)o(

kn),

k'>k

k為進隊次數,一般k≤

'>k≤k

≤常數。

這個演算法在一般的圖和隨機圖上面執行效果良好,但是在一些精心構造的圖上面就會卡到複雜度上限o(

nm)'>o(n

m)o(

nm)(每個點進隊m次)。

下面介紹另一種演算法。

這個演算法同樣是用bfs,每次找到距離源點最近的且未被用過的點,然後拿它去更新其它點,而這個點以後再也不會被更新到(除非有負環,那麼普通的dijistra就無法使用),這樣每個點只會用來更新一次其它點,每次尋找最近的點暴力複雜度為o(

n)'>o(n

)o(n

),然後更新的複雜度為它的度數(一般看作常數,除非菊花圖),所以複雜度總的來說為o(

n2)'>o(n

2)o(

n2)。

我們發現上述的演算法中,有乙個尋找最近點的o(

n)'>o(n

)o(n

),可以拿乙個資料結構維護,將o(

n)'>o(n

)o(n

)降到o(

logn

)'>o(l

ogn)

o(lo

gn),那麼維護最小值我們可以簡單的使用堆(自己手打或者stl的優先佇列),那麼該演算法就被優化到了o(

nlog

n)'>o(n

logn

)o(n

logn

),雖然一般圖和隨機圖跑的沒有sfpa快,但是在精心構造的圖上面,它複雜度的優秀性就體現出來了。(noi2018的day1t1可以說明)

多源最短路,就是求圖上的每乙個點到其它點的最短距離,樸素簡單的想法就是跑

n'>n

n遍單源最短路演算法,但是這裡還有其它的演算法可以解決這個問題。

這個演算法實質上是利用了動態規劃,dp的思想,我們定義如下狀態f[

i][j

]'>f[i

][j]

f[i]

[j],表示i⇒

j'>i⇒j

i⇒j的最短路長度,然後我們列舉乙個中轉點

k'>k

k,用它去不斷更新其它情況,轉移方程為f[

i][j

]=mi

n(f[

i][j

],f[

i][k

]+f[

k][j

])'>f[i

][j]

=min

(f[i

][j]

,f[i

][k]

+f[k

][j]

)f[i

][j]

=min

(f[i

][j]

,f[i

][k]

+f[k

][j]

)。這樣n3

'>n3n

3就可以求出多源最短路。(其實似乎跑

n'>n

n邊dijistra+堆優化好像才o(

n2lo

gn)'>o(n

2log

n)o(

n2lo

gn)的複雜度,不過floyd的常數明顯較小)。

這個演算法還有個用途,其實從它的轉移上都可以看出,我們可以求必須經過某個點的多源最短路,這時就不用列舉中轉點,而是已知中轉點,然後去更新答案,複雜度為o(

n2)'>o(n

2)o(

n2)。

a-star(a*)啟發式搜尋演算法,原理是dfs時利用乙個估計函式來剪枝。

後面待更新完善……

最短路演算法總結

1.floyd演算法 n 3複雜度 基本思想 開始設集合s的初始狀態為空,然後依次將0,1,n 1定點加入,同時用d i j 儲存從i到j,僅經過s中的定點的最短路徑,在初始時刻,d i j a i j 中間不經過任何節點,然後依次向s中插入節點,並進行如下更新 d k i j min 還可以使用乙...

最短路演算法總結

藉著usaco 3.26搞了幾天最短路。不得不說usaco真是菜鳥學習演算法的利器啊,有資料可以查錯。題上是乙個800 800的稀疏圖,需要求全源最短路 先用floyd試了一下。畢竟就三行,很好寫。時間o n3 裸交第九個點果然tle了,不過看題解有人水過了 就把邏輯語言改了一下,無向圖時間又可以優...

最短路演算法總結

dijkstra演算法 dijkstra 迪傑斯特拉 演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。最常見的問題就是 給你一張地圖,讓你求出指定的點到其餘各定點的最短路徑。演算法核心 每次找到離源點最近的乙個頂點,然後以該頂點為中心進行擴充套件,最終的到源點到其餘所有點...