Floyd算法又稱弗洛伊德算法,也叫做Floyd's algorithm,Roy–Warshall algorithm,Roy–Floyd algorithm, WFI algorithm。
Floyd算法是一種在有權圖中(有確定的非負的權值,不能存在環路)查找最短路徑的算法。該算法的一次簡單執行可以找出任意結點之間的最短路徑(盡管它沒有返回路徑的具體信息)。
思想:
Floyd算法通過比較圖中任意兩點間所有可能存在的路徑長度得到最短路徑長度。
我們定義一個函數shortestPath(i,j,k)代表從結點i到結點j的最短路徑且路徑上所有結點的編號均小於k。
兩結點間最短路徑只有兩種情況:1、從結點i經過若干編號小於k的結點到達結點j;2、從結點i經過若干編號小於k+1的結點到達結點j。
其中若最短路徑為第二種情況,則此事路徑可以分割為兩段:從結點i到結點k+1和從結點k+1到結點j,其中從結點i到結點k+1為最短路徑,從結點k+1到結點j也為最短路徑。
我們定義w(i,j)為結點i到結點j的邊的距離,如果兩結點之間沒有變則w(i,j)為無窮大。
那么以下等式
shortPath(i,j,0)=w(i,j);
shortestPath(i,j,k+1)=min(shortestPaht(i,j,k),shortestPaht(i,k+1,k)+shortestPath(k+1,j,k))
偽代碼如下:
let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) for each vertex v dist[v][v] ← 0 for each edge (u,v) dist[u][v] ← w(u,v) // the weight of the edge (u,v) for k from 1 to |V| for i from 1 to |V| for j from 1 to |V| if dist[i][j] > dist[i][k] + dist[k][j] dist[i][j] ← dist[i][k] + dist[k][j] end if
C代碼
#include <stdio.h> #define N 10//定義頂點個數 int arr[N][N];//定義二維數組,其初始值為該圖的鄰接矩陣 int main(){ int len; while(scanf("%d",&len)!=EOF){ for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ arr[i][j]=-1;//初始化二維數組,因為floyd不存在負數權值,故我們使用-1代替無窮大 } } int i,j,c;//定義結點及權值 while(len--){ scanf("%d %d %d",&i,&j,&c);//輸入邊的兩個結點及邊的距離 arr[i][j]=arr[j][i]=c; } // for(int k=0;k<len;k++){ for(int i=0;i<len;i++){ for(int j=0;j<len;j++){ if(arr[i][k]==-1||arr[k][j]==-1)//如果兩個之中有一個是無窮大,則必有arr[i][j]不能經過k結點聯結 continue; if(arr[i][j]==-1||arr[i][k]+arr[k][j]<arr[i][j])//如果經過k結點后路徑變短,則更新路徑 arr[i][j]=arr[j][i]=arr[i][k]+arr[k][j]; } } } } return 0; }
