最短路徑問題:弗洛伊德算法(Floyd)

Floyd算法ios

1.定義概覽算法

Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,能夠正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。Floyd-Warshall算法的時間複雜度爲O(N3),空間複雜度爲O(N2)。閉包

 

2.算法描述spa

1)算法思想原理:code

     Floyd算法是一個經典的動態規劃算法。用通俗的語言來描述的話,首先咱們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,咱們須要爲這個目標從新作一個詮釋(這個詮釋正是動態規劃最富創造力的精華所在)blog

      從任意節點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的最短路徑的距離。ci

2).算法描述:string

a.從任意一條單邊路徑開始。全部兩點之間的距離是邊的權,若是兩點之間沒有邊相連,則權爲無窮大。   it

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

3).Floyd算法過程矩陣的計算----十字交叉法

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

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

 

相應計算方法以下:

 

 

最後A3即爲所求結果。

【例題】:最短路問題

【問題描述】:

  平面上有n(n<=100),每一個點的座標均在-10000~10000之間。其中的一些點之間有連線。

  如有連線,則表示能夠從一個點到達另外一個點,即兩個點之間有通路,通路的距離爲兩點之間的距離,如今的任務是找出從一點到另外一個點的最短距離。

【輸入格式】:

第一行:n。

第二行到第n+1行:每行兩個整數,描述了一個點的座標。

第n+2行爲一個整數m,表示圖中的連線的個數。

此後的m行,每行一個連線,有兩個整數i和j組成,表示第i 和j個點之間有連線。

最後一行:兩個整數:s,t,分別表示起點和終點的座標。

【輸出格式】:

一個整數表示從s到t的最短路的距離。

【輸入樣例】:

5

0 0

2 0

2 2

0 2

3 1

5

1 2

1 3

1 4

2 5

3 5

1 5

【輸出樣例】:3.41

【參考程序】:

#include<iostream> #include<cstdio> #include<cmath> #include<cstring>
using namespace std; int a[101][3]; double f[101][101]; int n,i,j,x,y,k,m,s,e; int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i][1]>>a[i][2]; cin>>m; memset(f,0x7f,sizeof) for(int i=1;i<=m;i++) { cin>>x>>y; f[y][x]=f[x][y]=sqrt(pow(a[x][1]-a[y][1],2)+pow(double(a[x][2]-a[y][2]),2)); } cin>>s>>e; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(i!=j)&&(i!=k)&&(k!=j) if(f[i][k]+f[k][j]<f[i][j]) f[i][j]=f[i][k]+f[k][j]; printf("%.2lf\n",,f[s][e]); return 0; }
相關文章
相關標籤/搜索