在圖的問題中,經常會遇到求兩個點之間的最短路徑的問題,而且無法確定起點和終點,即多源最短路徑問題。而弗洛伊德演算法就是解決這一類問題的。和迪傑斯特拉演算法類似,迪傑斯特拉演算法對一對結點做鬆弛操作,而弗洛伊德是對圖中每乙個結點對進行一輪鬆弛操作。迪傑斯特拉演算法詳解:
遍歷每個結點對,對每個結點對做鬆弛操作。結點對的鬆弛操作在圖論裡會經常用到,鬆弛操作用來求乙個結點對之間的最短路徑。假設圖中有n個點,對圖中結點對的鬆弛操作的思路為(以結點對1和n為例):
1、建圖,用乙個二維陣列edge[i][j]來表示i到j之間的距離。遍歷每個結點對,鬆弛操作中edge陣列表示兩個點之間當前的最短距離。
2、允許經過前乙個點,即2,進行中轉,判斷edge[1][n]和edge[1][2]+edge[2][n]之間的大小。若edge[1][2]+edge[2][n]更小,則表示通過點2中轉的話1到n的距離比不中轉更短。此時更新edge[1][n]的值為edge[1][2]+edge[2][n]。由於edge陣列表示兩個點之間當前的最短距離,則這時經過點2中轉的結果已經隱含體現在了edge[1][n]中,之後的鬆弛操作都是在這一基礎上進行。
2.1、然後允許經過前兩個點,即2、3,進行中轉,判斷edge[1][n]和edge[1][3]+edge[3][n]之間的大小,若edge[1][3]+edge[3][n]更小,則表示通過點3中轉的話1到n的距離比不中轉更短。此時更新edge[1][n]的值為edge[1][3]+edge[3][n]。由於edge陣列表示兩個點之間當前的最短距離,則這時經過點2、3中轉的結果已經隱含體現在了edge[1][n]中,之後的鬆弛操作都是在這一基礎上進行。
3、重複2過程,允許經過前3~n-1個結點進行中轉,儲存每一次中轉與否最短路徑的變化。最後得到的edge[1][n]就是1到n的最短路徑的路徑和。
4、對圖中的每乙個結點對都進行鬆弛操作,此時edge[i][j],就是從i到j的最短路徑,不管i和j是幾,都能得到答案。
#include#define inf 999999 //表示兩個點之間不連通
#define max 105
using namespace std;
int m,n,edge[max][max];
int main()
//建圖
while(m--)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
//若結點對跟中轉點不連通,則跳過
if(edge[i][k]!=inf && edge[k][j]!=inf && edge[i][j]>(edge[i][k]+edge[k][j]))
//更新最短路徑
edge[i][j]=edge[i][k]+edge[k][j];
cout
}
弗洛伊德演算法 多源最短路徑
圖的儲存 鄰接矩陣 define maxsize 100 define inf 65535 typedef struct mgrap 建立圖。單元最短路徑的實 現 void creategrap mgrap g 初始化矩陣 for int i 0 in i cout 請輸入邊的資訊 起始邊和終止邊 ...
弗洛伊德演算法求最短路徑
include includeusing namespace std 鄰接矩陣的型別定義 define max 10000000 define max vertex num 20 typedef struct mgraph 構造有向網的鄰接矩陣 void createdn am mgraph g,i...
最短路徑 弗洛伊德 Floyd 演算法
弗洛伊德 floyd 演算法 是解決任意兩點間的最短路徑的一種演算法 floyd演算法是乙個經典的動態規劃演算法 用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做乙個詮釋 這個詮釋正是動態規劃最富創造力的精華所在 從任意節點i到任意...