轉載:https://blog.csdn.net/qq_35644234/article/details/60875818算法
弗洛伊德算法是解決任意兩點間的最短路徑的一種算法,能夠正確處理有向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。閉包
經過Floyd計算圖G=(V,E)中各個頂點的最短路徑時,須要引入兩個矩陣,矩陣S中的元素a[i][j]表示頂點i(第i個頂點)到頂點j(第j個頂點)的距離。矩陣P中的元素b[i][j],表示頂點i到頂點j通過了b[i][j]記錄的值所表示的頂點。oop
假設圖G中頂點個數爲N,則須要對矩陣D和矩陣P進行N次更新。初始時,矩陣D中頂點a[i][j]的距離爲頂點i到頂點j的權值;若是i和j不相鄰,則a[i][j]=∞,矩陣P的值爲頂點b[i][j]的j的值。 接下來開始,對矩陣D進行N次更新。第1次更新時,若是」a[i][j]的距離」 > 「a[i][0]+a[0][j]」(a[i][0]+a[0][j]表示」i與j之間通過第1個頂點的距離」),則更新a[i][j]爲」a[i][0]+a[0][j]」,更新b[i][j]=b[i][0]。 同理,第k次更新時,若是」a[i][j]的距離」 > 「a[i][k-1]+a[k-1][j]」,則更新a[i][j]爲」a[i][k-1]+a[k-1][j]」,b[i][j]=b[i][k-1]。更新N次以後,操做完成!spa
補充:如下面圖爲例子,b[i][j]中存儲的是Vi~Vj之間的中介點,b[i][j]初始值爲j,好比V0~V3最短路徑是V0-->V2-->V1-->v3,在計算最短路徑時轉換爲V0-->V2的距離加上V2-->V3的最短距離,接下來相似於遞歸,V2-->V3的最短路徑就是以V1爲中介點,V2-->V1的距離加上V1-->V3的距離。所以,b[0][3]=2.net
將總體分爲兩個步驟code
1.計算metrixD矩陣(兩頂點之間的最短距離)和P矩陣(兩頂點的中介點)orm
#include <stdio.h> #include <stdlib.h> void Create_metrixD_P(int** metrixD, int **P ,int VerNum, int EdgNum) { int x, y, Weight, edg_count = 0; int i, j, k; for (i = 0; i < VerNum; ++i) { for (j = 0; j < VerNum; ++j) { metrixD[i][j] = INT_MAX; P[i][j] = j; } } while (edg_count < EdgNum) { scanf("%d%d%d", &x, &y, &Weight); metrixD[x - 1][y - 1] = Weight; edg_count++; } } //Floyd algorithm void Floyd(int **metirxD, int **P, int VerNum) { int n, x, y, temp = 0; //The triple loop looks for shortest paths and weights for (n = 0; n < VerNum; ++n) { for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { //The distance between two vertices is compared to the distance through a vertex temp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]); if (temp < metirxD[x][y]) { //Update matrix information metirxD[x][y] = temp; P[x][y] = n; } } } } } void Show_metrixD_P(int** metrixD, int **P, int VerNum) { int x, y; printf("metrixD:\n"); for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { if (metrixD[x][y] == INT_MAX) { printf("∞ "); } else { printf("%d ", metrixD[x][y]); } } printf("\n"); } printf("P:\n"); for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { printf("%d ", P[x][y]); } printf("\n"); } } int main(void) { int VerNum, EdgNum, i; int** metrixD, ** P; printf("Enter the number of vertices and edges:"); scanf("%d%d", &VerNum, &EdgNum); metrixD = (int**)malloc(VerNum * sizeof(int)); P = (int**)malloc(VerNum * sizeof(int)); for (i = 0; i < VerNum; ++i) { metrixD[i] = (int*)malloc(VerNum * sizeof(int)); P[i] = (int*)malloc(VerNum * sizeof(int)); } printf("Input vertices and weights:"); Create_metrixD_P(metrixD, P, VerNum, EdgNum); Floyd(metrixD, P, VerNum); Show_metrixD_P(metrixD, P, VerNum); for (i = 0; i < VerNum; ++i) { free(metrixD[i]); free(P[i]); } free(metrixD); free(P); return 0; }
2.輸出頂點之間的最短距離與路徑blog
#include <stdio.h> #include <stdlib.h> #define VEXNUM 5 //Adjacency matrix: shows the distance between vertices int metirxD[VEXNUM][VEXNUM] = { INT_MAX,10, 5, INT_MAX,INT_MAX, INT_MAX,INT_MAX,2, 1, INT_MAX, INT_MAX,3, INT_MAX,9, 2, INT_MAX,INT_MAX,INT_MAX,INT_MAX,4, 7, INT_MAX,INT_MAX,5, INT_MAX }; //Path: passing vertex between two vertices int P[VEXNUM][VEXNUM] = { 0,1,2,3,4, 0,1,2,3,4, 0,1,2,3,4, 0,1,2,3,4, 0,1,2,3,4 }; //Floyd algorithm void Floyd() { int n, x, y, temp = 0; //The triple loop looks for shortest paths and weights for (n = 0; n < VEXNUM; ++n) { for (x = 0; x < VEXNUM; ++x) { for (y = 0; y < VEXNUM; ++y) { //The distance between two vertices is compared to the distance through a vertex temp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]); if (temp < metirxD[x][y]) { //Update matrix information metirxD[x][y] = temp; P[x][y] = n; } } } } } void Show_Path() { int x, y, temp = 0; //Output the shortest path between two vertices for (x = 0; x < VEXNUM - 1; ++x) { for (y = x + 1; y < VEXNUM; ++y) { printf("V%d-->V%d weight:%d path:V%d", x, y, metirxD[x][y], x); temp = P[x][y]; while (temp != y) { printf("-->V%d", temp); temp = P[temp][y]; } printf("-->V%d", y); printf("\n"); } } } int main(void) { Floyd(); Show_Path(); return 0; }
#include <stdio.h> #include <stdlib.h> void Create_metrixD_P(int** metrixD, int **P ,int VerNum, int EdgNum) { int x, y, Weight, edg_count = 0; int i, j, k; for (i = 0; i < VerNum; ++i) { for (j = 0; j < VerNum; ++j) { metrixD[i][j] = INT_MAX; P[i][j] = j; } } while (edg_count < EdgNum) { scanf("%d%d%d", &x, &y, &Weight); metrixD[x - 1][y - 1] = Weight; edg_count++; } } //Floyd algorithm void Floyd(int **metirxD, int **P, int VerNum) { int n, x, y, temp = 0; //The triple loop looks for shortest paths and weights for (n = 0; n < VerNum; ++n) { for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { //The distance between two vertices is compared to the distance through a vertex temp = (metirxD[x][n] == INT_MAX || metirxD[n][y] == INT_MAX) ? INT_MAX : (metirxD[x][n] + metirxD[n][y]); if (temp < metirxD[x][y]) { //Update matrix information metirxD[x][y] = temp; P[x][y] = n; } } } } } void Show_metrixD_P(int** metrixD, int **P, int VerNum) { int x, y; printf("metrixD:\n"); for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { if (metrixD[x][y] == INT_MAX) { printf("∞ "); } else { printf("%d ", metrixD[x][y]); } } printf("\n"); } printf("P:\n"); for (x = 0; x < VerNum; ++x) { for (y = 0; y < VerNum; ++y) { printf("%d ", P[x][y]); } printf("\n"); } } void Show_Path(int **metirxD, int **P, int VerNum) { int x, y, temp = 0; //Output the shortest path between two vertices for (x = 0; x < VerNum - 1; ++x) { for (y = x + 1; y < VerNum; ++y) { printf("V%d-->V%d weight:%d path:V%d", x, y, metirxD[x][y], x); temp = P[x][y]; while (temp != y) { printf("-->V%d", temp); temp = P[temp][y]; } printf("-->V%d", y); printf("\n"); } } } int main(void) { int VerNum, EdgNum, i; int** metrixD, ** P; printf("Enter the number of vertices and edges:"); scanf("%d%d", &VerNum, &EdgNum); metrixD = (int**)malloc(VerNum * sizeof(int)); P = (int**)malloc(VerNum * sizeof(int)); for (i = 0; i < VerNum; ++i) { metrixD[i] = (int*)malloc(VerNum * sizeof(int)); P[i] = (int*)malloc(VerNum * sizeof(int)); } printf("Input vertices and weights:"); Create_metrixD_P(metrixD, P, VerNum, EdgNum); Floyd(metrixD, P, VerNum); Show_metrixD_P(metrixD, P, VerNum); Show_Path(metrixD, P, VerNum); for (i = 0; i < VerNum; ++i) { free(metrixD[i]); free(P[i]); } free(metrixD); free(P); return 0; }