Floyd 演算法求多源最短路徑

2021-09-08 06:58:43 字數 3100 閱讀 6391

floyd演算法:

floyd演算法用來找出每對頂點之間的最短距離,它對圖的要求是,既可以是無向圖也可以是有向圖,邊權可以為負,但是不能存在負環(可根據最小環的正負來判定).

基本演算法:

floyd演算法基於動態規劃的思想,以 u 到 v 的最短路徑至少經過前 k 個點為轉移狀態進行計算,通過 k 的增加達到尋找最短路徑的目的.當 k 增加 1 時,最短路徑要麼不邊,如果改變,必經過第 k 各點,也就是說當起點 u 到第 k 個點的最短距離加上第 k 個點到終點 v 的最短路徑小於不經過第 k 個節點的最優最短路經長度的時候更新 u 到 v 的最短距離. 當 k = n 時, u 到 v 的最短路徑就確定了. 

偽**:

圖的儲存用鄰接矩陣 gra 來記錄,如果 u 與 v 之間沒有邊直接相連,則 gra[u][v] = inf; dist 記錄最終的最短路. pre[i][j] 儲存 i 到 j 路徑中 i 的後乙個節點.

1): 初始化:將 gra 中的資料複製到 dist 中作為每對頂點間的最短路的初值, pre[i][j] = j;

2): k 從 1 到 n 迴圈 n 次, 每次迴圈中列舉圖中不同的兩點 u, v, 如果 dist[u][v] > dist[u][k] + dist[k][v], 則更新 dist[u][v] = dist[u][k] + dist[k][v], 更新 pre[u][v] = pre[u][k].

3): 最後 dist[u][v] 陣列中儲存的就是 u 到 v 的最短距離, u 到 v 的路徑, 則可以按照順序查詢就好了.

以圖為例:

有乙個如下的無向圖, 「d」陣列儲存最短路值, 「p」 陣列儲存最短路徑:

假設現在每對頂點之間的路徑只允許經過點 「1」 , 則更新後的每對頂點之間的距離:

這裡看到點 「2」 到點 「3」 的距離經過點 「1」 得到了更新,同時更新了用於記錄路徑的 p 陣列.

第二步,允許每對頂點之間的最短路徑經過點 「1」 和點 「2」,則更新後的陣列為:

可以看到得到更新的路徑為:

1 ---> 4, 經過點 「2」 得到更新

1 ---> 5, 經過點 「2」 得到更新

3 ---> 5. 經過點 「1 --- > 2」 得到更新

第三步: 允許經過點 「1」, 「2」 和點 「3」 則更新後的陣列為:

這則說明,上一步的最短路徑不需要更新.

第四步, 允許經過點 「1」, 「2」 , 「3」 和點 「4」 則更新後的陣列為:

可以看到 3 ---> 5 的路徑經過點 「4」 得到了更新(原先是 3 ---> 1 ---> 2 ---> 5, w = 9)

第五步, 允許任意兩點之間的最短路徑可以經過全部點,則更新後的陣列為:

這次得到更新的路徑為:

1 ---> 4 的路徑. 更新為 「1 ---> 2 ---> 5 ---> 4, w = 5」 (原路徑為 1 ---> 2 ---> 4, w = 7)

2 ---> 3 的路徑. 更新為 「2 ---> 5 ---> 4 ---> 3, w = 7」 (原路經為 2 ---> 1 ---> 3, w = 8)

2 ---> 4 的路徑. 更新為 「2 --> 5 --> 4, w = 2」 (原路徑為 2 ---> 4, w = 4)

無向圖反之亦然.

至此最短路徑就尋找完畢. dist[i][j] 陣列裡面儲存的就是 i 到 j 的最短距離.如果要查尋路徑, 則按照查陣列 pre 就好.比如查詢 「2」 到 「3」 的路徑:

則尋找     pre[2][3] = 5,  2 ---> 5

繼續尋找  pre[5][3] = 4,  2 ---> 5 ---> 4

繼續尋找  pre[4][3] = 3, 2 ---> 5 ---> 4 ---> 3

由於此時 i = j = 3, 則 「2」 到 「3」 的最短路徑已找到為: 2 ---> 5 ---> 4 ---> 3

1 #include 2

3 typedef long

long

ll;4

const

int maxn = 100;5

const

int inf = 0x3f3f3f3f;6

using

namespace

std;78

int pre[maxn + 3][maxn + 3], dist[maxn + 3][maxn + 3]; //

pre 儲存路徑; dist 儲存最短距離

9void floyd(int n, int gra[maxn + 3

]) 18}19

}20}21

}2223int pfpath(int u, int v)

28 cout << u <

3031

int gra[maxn + 3][maxn + 3

];32

intmain()

38for(int i = 0; i < m; i++)

42floyd(n, gra);43}

44return0;

45 }

posted @

2018-02-27 11:23

tangent_1231 閱讀(

...)

編輯收藏

Floyd 演算法求多源最短路徑

floyd演算法 floyd演算法用來找出每對頂點之間的最短距離,它對圖的要求是,既可以是無向圖也可以是有向圖,邊權可以為負,但是不能存在負環 可根據最小環的正負來判定 基本演算法 floyd演算法基於動態規劃的思想,以 u 到 v 的最短路徑至少經過前 k 個點為轉移狀態進行計算,通過 k 的增加...

Floyd演算法 多源最短路徑

解決稠密圖較好 準備工作 include floyd演算法解決稠密圖時更好 include include include using namespace std const int maxv 100 定義邊 typedef struct enode edge 定義鄰接矩陣儲存的圖 typedef ...

多源最短路 Floyd演算法

問題的提出 已知乙個有向網 或者無向網 對每一對定點vi vj,要求求出vi與vj之間的最短路徑和最短路徑的長度。解決該問題有以下兩種方法 1 輪流以每乙個定點為源點,重複執行dijkstra演算法或者bellman ford演算法n次,就可以求出每一對頂點之間的最短路徑和最短路徑的長度,總的時間複...