200117(最短路徑的Floyd演算法(dp))

2021-10-02 05:11:28 字數 2541 閱讀 9560

floyd演算法是乙個經典的動態規劃演算法。簡單地說,首先我們的目標是尋找從頂點 i 到頂點 j 的最短路徑。

從任意頂點i到任意頂點j的最短路徑不外乎2種可能,一是直接從 i 到 j ,二是從 i 經過若干個中間頂點到 j 。所以,我們假設d(i,j)為頂點 i 到頂點 j 的最短路徑的距離,對於每乙個頂點 k,我們檢查d(i,k) + d(k,j) < d(i,j)是否成立,如果成立,證明從 i 到 k 再到 j 的路徑比 i 直接到 j 的路徑短,我們便設定d(i,j) = d(i,k) + d(k,j),這樣一來,當我們遍歷完所有頂點 k,d(i,j)中記錄的便是 i 到 j 的最短路徑的距離。

核心思想:本質就是逐步嘗試在原路徑中每次加入乙個頂點k作為中間結點,所以**的最外層迴圈就是for (int k = 0; k < g.numvexs; k++)//中間點k

演算法過程:

1)首先把初始化距離陣列d為圖的鄰接矩陣arc,路徑陣列p初始化為p[i][j]=j(初始化時由於 i 是直接到 j 的,所以 i 的後繼結點就是 j );

2)對於每一對頂點 i 和 j,遍歷所有頂點,看看是否存在乙個頂點 k 使得從 i 到 k 再加上 k 到 j 比直接從 i 到 j 的路徑更短。如果是就更新d[i][j]。

遞推關係式為:

如果 d[i][k]+d[k][j] < d[i][j]

則d[i][j] = d[i][k]+d[k][j]

注意!!!:仔細思考遞推關係式會發現由於d[i][i]始終為0,所以 i 、j 、k 在for迴圈中是順序還是逆序都沒關係。

舉個例子,比如我在求dk [5][8]假設此時中間頂點為4,那麼dk [5][8]=min,那麼我接下來求其它的dk [i][j]時肯定不會用到dk [5][8];(因為這一輪k的值固定為4了

又比如我在求dk [4][8]假設此時中間頂點為4,由於d[4][4]為0,所以dk [4][8]仍然等於dk-1 [4][8];

綜上,所以dk和dk-1可以在同乙個陣列內完成更新,不用擔心子問題的解被覆蓋的風險

#include

using

namespace std;

#define maxvex 9

#define infinity 65536

typedef

struct

mgraph;

void

shortestpath_floyd

(mgraph&g)

;void

printpath

(mgraph&g,

int v,

int w)

;int

main()

g.d[0]

[1]=

1; g.d[0]

[2]=

5;g.d[1]

[2]=

3; g.d[1]

[3]=

7; g.d[1]

[4]=

5;g.d[2]

[4]=

1; g.d[2]

[5]=

7;g.d[3]

[4]=

2; g.d[3]

[6]=

3;g.d[4]

[5]=

3; g.d[4]

[6]=

6; g.d[4]

[7]=

9;g.d[5]

[7]=

5;g.d[6]

[7]=

2; g.d[6]

[8]=

7;g.d[7]

[8]=

4;for(

int i =

0; i < g.numvexs; i++

)for

(int j =

0; j < g.numvexs; j++

)for

(int i =

0; i < g.numvexs; i++

)for

(int j =

0; j < g.numvexs; j++

) g.p[i]

[j]= j;

//以上為d和p的初始化

shortestpath_floyd

(g);

printpath

(g,0,8

);system

("pause");

return0;

}void

shortestpath_floyd

(mgraph&g)}}

void

printpath

(mgraph&g,

int v,

int w)

cout << w << endl;

}

時間複雜度o(n3)

Codeup最短路徑 最短路徑

n個城市,標號從0到n 1,m條道路,第k條道路 k從0開始 的長度為2 k,求編號為0的城市到其他城市的最短距離。第一行兩個正整數n 2 n 100 m m 500 表示有n個城市,m條道路,接下來m行兩個整數,表示相連的兩個城市的編號。n 1行,表示0號城市到其他城市的最短路,如果無法到達,輸出...

Codeup最短路徑 最短路徑問題

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。輸入n,m,點的編號是1 n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t 起點s,...

最短路徑之最短路徑問題

提交 狀態 討論版 命題人 外部匯入 題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點間的直線距離。現在的 任務是找出從一點到另一點之間的最短路徑。輸入共n m 3行,...