最短路演算法總結

2021-05-22 13:14:25 字數 2119 閱讀 4971

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

還可以使用乙個二維陣列path指示最短路徑。

path[i][j]給出從定點i到j的最短路徑上,定點i的前乙個頂點

**相當簡單,最容易的實現方法:

然後可以通過遞迴得出路徑的。。

2.dijstra演算法

單源最短路問題,先加入源,維持一張表來儲存此時到源中的最短距離,選取最小的加入,然後更新表,不斷的加入直到目的地在源中。僅適用於正邊權的時侯,因為這時我們可以保證任意加入的點已經找到了源到該點的距離。

3.bellman-ford演算法

最優性原理

最優性原理介紹及簡單證明見:http://blog.csdn.net/liguanxing/article/details/7401798

它是最優性原理的直接應用,演算法基於以下事實:

如果最短路存在,則每個頂點最多經過一次,因此不超過

n-1條邊;

長度為k

的路由長度為

k-1的路加一條邊得到;

由最優性原理,只需依次考慮長度為1,

2,…,

k-1的最短路。

適用條件&範圍

單源最短路徑

(從源點

s到其它所有頂點

v);

有向圖&

無向圖(

無向圖可以看作

(u,v),(v,u)

同屬於邊集

e的有向圖);

邊權可正可負

(如有負權迴路輸出錯誤提示);

差分約束系統(需要首先構造約束圖,構造不等式時

>=

表示求最小值

,作為最長路,

<=

表示求最大值

,作為最短路。

<=

構圖時,

有負環說明無解;求不出最短路(為

inf)為任意解。

>=

構圖時類似)。

演算法描述

1)對每條邊進行

|v|-1

次relax操作;

2)如果存在

(u,v)∈e

使得dis[u]+w則存在負權迴路;否則

dis[v]即為s

到v的最短距離

,pre[v]

為前驅。

演算法時間複雜度

o(ve)

。因為演算法簡單,適用範圍又廣,雖然複雜度稍高,仍不失為乙個很實用的演算法。

改進和優化

如果迴圈

n-1次以前已經發現不存在緊邊則可以立即終止;

4.spfa演算法

spfa(shortest path faster algorithm)

是bellman-ford

演算法的一種佇列實現,減少了不必要的冗餘計算。

它可以在

o(ke)

的時間複雜度內求出源點到其他所有點的最短路徑,可以處理負邊。

演算法流程

spfa

對bellman-ford

演算法優化的關鍵之處在於意識到:只有那些在前一遍鬆弛中改變了距離估計值的點,才可能引起他們的鄰接點的距離估計值的改變。因此,演算法大致流程是用乙個佇列來進行維護,即用乙個先進先出的佇列來存放被成功鬆弛的頂點。初始時,源點

s入隊。當佇列不為空時,取出隊首頂點,對它的鄰接點進行鬆弛。如果某個鄰接點鬆弛成功,且該鄰接點不在佇列中,則將其入隊。經過有限次的鬆弛操作後,佇列將為空,演算法結束。

spfa

演算法的實現,需要用到乙個先進先出的佇列

queue

和乙個指示頂點是否在佇列中的標記陣列

mark

。為了方便查詢某個頂點的鄰接點,圖採用臨界表儲存。

注意:spfa演算法只有在不存在負權環的情況下可以正常的結束,如果存在負權環,那麼將

總有頂點在入隊和出隊往返,佇列無法為空,這種情況下

spfa

無法正常結束。可以通過新增乙個變數表示每個頂點進入佇列的次數,如果大於|v|那麼就可以說明存在負權環

最短路演算法總結

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

最短路演算法總結

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

最短路演算法總結

顧名思義就是尋找乙個源點到其它的點的最短路,暴力的dfs或者bfs就不說了,下面講講幾種單源最短路的演算法。這個演算法的實質就是利用bfs,我們先將源點到源點的距離設定為0,到其它的距離設定為無窮大 一般0x7fffffff 然後將源點加入佇列,用隊首的點去bfs,更新它能到達且能更新的的點,然後將...