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行,...