最短路径--Floyd算法
Floyd算法
1.定義概覽
Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用于計算有向圖的傳遞閉包。Floyd-Warshall算法的時間復雜度為O(N3),空間復雜度為O(N2)。
?
2.算法描述
1)算法思想原理:
???? Floyd算法是一個經典的動態規劃算法。用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做一個詮釋(這個詮釋正是動態規劃最富創造力的精華所在)
????? 從任意節點i到任意節點j的最短路徑不外乎2種可能,1是直接從i到j,2是從i經過若干個節點k到j。所以,我們假設Dis(i,j)為節點u到節點v的最短路徑的距離,對于每一個節點k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j的路徑比i直接到j的路徑短,我們便設置Dis(i,j) = Dis(i,k) + Dis(k,j),這樣一來,當我們遍歷完所有節點k,Dis(i,j)中記錄的便是i到j的最短路徑的距離。
2).算法描述:
a.從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。
b.對于每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比己知的路徑更短。如果是更新它。
3).Floyd算法過程矩陣的計算----十字交叉法(暫時沒看懂,望大神指教)
方法:兩條線,從左上角開始計算一直到右下角 如下所示
給出矩陣,其中矩陣A是鄰接矩陣,而矩陣Path記錄u,v兩點之間最短路徑所必須經過的點
相應計算方法如下:
最后A3即為所求結果
?
3.算法代碼實現:
1 typedef struct 2 { 3 char vertex[VertexNum]; //頂點表 4 int edges[VertexNum][VertexNum]; //鄰接矩陣,可看做邊表 5 int n,e; //圖中當前的頂點數和邊數 6 }MGraph; 7 8 void Floyd(MGraph g) 9 { 10 int A[MAXV][MAXV]; 11 int path[MAXV][MAXV]; 12 int i,j,k,n=g.n; 13 for(i=0;i<n;i++) 14 for(j=0;j<n;j++) 15 { 16 A[i][j]=g.edges[i][j]; 17 path[i][j]=-1; 18 } 19 for(k=0;k<n;k++) 20 { 21 for(i=0;i<n;i++) 22 for(j=0;j<n;j++) 23 if(A[i][j]>(A[i][k]+A[k][j])) 24 { 25 A[i][j]=A[i][k]+A[k][j]; 26 path[i][j]=k; 27 } 28 } 29 }算法時間復雜度:O(n3)
?
結合代碼 并參照上圖所示 我們來模擬執行下 這樣才能加深理解:
第一關鍵步驟:當k執行到x,i=v,j=u時,計算出v到u的最短路徑要通過x,此時v、u聯通了。
第二關鍵步驟:當k執行到u,i=v,j=y,此時計算出v到y的最短路徑的最短路徑為v到u,再到y(此時v到u的最短路徑上一步我們已經計算過來,直接利用上步結果)。
第三關鍵步驟:當k執行到y時,i=v,j=w,此時計算出最短路徑為v到y(此時v到y的最短路徑長在第二步我們已經計算出來了),再從y到w。
依次掃描每一點(k),并以該點作為中介點,計算出通過k點的其他任意兩點(i,j)的最短距離,這就是floyd算法的精髓!同時也解釋了為什么k點這個中介點要放在最外層循環的原因.
?
hdu-2544代碼:
#include <stdio.h> #include <string.h> #define MAX 1000000 int map[110][110]; int n; void flyod() {int i,j,k;for(k=1;k<=n;k++)for(i=1;i<=n;i++){for(j=1;j<=n;j++)if(map[i][j]>(map[i][k]+map[k][j]))map[i][j]=map[i][k]+map[k][j];}printf("%d\n",map[1][n]); } int main() {int m;while(scanf("%d %d",&n,&m),n||m){int i,j,a,b,c;for(i=0;i<=n;i++)for(j=0;j<=n;j++)map[i][j]=MAX;for(i=0;i<m;i++){scanf("%d %d %d",&a,&b,&c);if(c<map[a][b])map[a][b]=map[b][a]=c;}flyod();}return 0; } //ac //flyod算法,31ms轉載于:https://www.cnblogs.com/xl1027515989/p/3605553.html
總結
以上是生活随笔為你收集整理的最短路径--Floyd算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT+vs2010下改变可执行程序的图标
- 下一篇: DrJava试用笔记