日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最短路径--Floyd算法

發(fā)布時間:2023/12/2 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短路径--Floyd算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Floyd算法

1.定義概覽

Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負(fù)權(quán)的最短路徑問題,同時也被用于計算有向圖的傳遞閉包。Floyd-Warshall算法的時間復(fù)雜度為O(N3),空間復(fù)雜度為O(N2)。

?

2.算法描述

1)算法思想原理:

???? Floyd算法是一個經(jīng)典的動態(tài)規(guī)劃算法。用通俗的語言來描述的話,首先我們的目標(biāo)是尋找從點i到點j的最短路徑。從動態(tài)規(guī)劃的角度看問題,我們需要為這個目標(biāo)重新做一個詮釋(這個詮釋正是動態(tài)規(guī)劃最富創(chuàng)造力的精華所在)

????? 從任意節(jié)點i到任意節(jié)點j的最短路徑不外乎2種可能,1是直接從i到j(luò),2是從i經(jīng)過若干個節(jié)點k到j(luò)。所以,我們假設(shè)Dis(i,j)為節(jié)點u到節(jié)點v的最短路徑的距離,對于每一個節(jié)點k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j(luò)的路徑比i直接到j(luò)的路徑短,我們便設(shè)置Dis(i,j) = Dis(i,k) + Dis(k,j),這樣一來,當(dāng)我們遍歷完所有節(jié)點k,Dis(i,j)中記錄的便是i到j(luò)的最短路徑的距離。

2).算法描述:

a.從任意一條單邊路徑開始。所有兩點之間的距離是邊的權(quán),如果兩點之間沒有邊相連,則權(quán)為無窮大。   

b.對于每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比己知的路徑更短。如果是更新它。

3).Floyd算法過程矩陣的計算----十字交叉法(暫時沒看懂,望大神指教)

方法:兩條線,從左上角開始計算一直到右下角 如下所示

給出矩陣,其中矩陣A是鄰接矩陣,而矩陣Path記錄u,v兩點之間最短路徑所必須經(jīng)過的點

相應(yīng)計算方法如下:

最后A3即為所求結(jié)果

?

3.算法代碼實現(xiàn):

1 typedef struct 2 { 3 char vertex[VertexNum]; //頂點表 4 int edges[VertexNum][VertexNum]; //鄰接矩陣,可看做邊表 5 int n,e; //圖中當(dāng)前的頂點數(shù)和邊數(shù) 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 }

算法時間復(fù)雜度:O(n3)

?

結(jié)合代碼 并參照上圖所示 我們來模擬執(zhí)行下 這樣才能加深理解:
第一關(guān)鍵步驟:當(dāng)k執(zhí)行到x,i=v,j=u時,計算出v到u的最短路徑要通過x,此時v、u聯(lián)通了。
第二關(guān)鍵步驟:當(dāng)k執(zhí)行到u,i=v,j=y,此時計算出v到y(tǒng)的最短路徑的最短路徑為v到u,再到y(tǒng)(此時v到u的最短路徑上一步我們已經(jīng)計算過來,直接利用上步結(jié)果)。
第三關(guān)鍵步驟:當(dāng)k執(zhí)行到y(tǒng)時,i=v,j=w,此時計算出最短路徑為v到y(tǒng)(此時v到y(tǒng)的最短路徑長在第二步我們已經(jīng)計算出來了),再從y到w。

依次掃描每一點(k),并以該點作為中介點,計算出通過k點的其他任意兩點(i,j)的最短距離,這就是floyd算法的精髓!同時也解釋了為什么k點這個中介點要放在最外層循環(huán)的原因.

?

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

轉(zhuǎn)載于:https://www.cnblogs.com/xl1027515989/p/3605553.html

總結(jié)

以上是生活随笔為你收集整理的最短路径--Floyd算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。