[圖] 6.3.1 Floyd演算法|佛洛依德
阿新 • • 發佈:2018-12-15
文章目錄
測試資料
結果
實現
void PrintPath(int u, int v, int path[][maxSize]) {
int mid;
if (path[u][v]==-1) {
//直接輸出,沒有中間點
printf("<%c,%c> ", vertexs[u], vertexs[v]);
} else { //有中間點
mid = path[u][v];
PrintPath(u, mid, path);
PrintPath(mid, v, path);
}
}
void Floyd(int n, int MGraph[ ][maxSize], int path[][maxSize]) {
int i,j,v;
int A[maxSize][maxSize]; //最短路徑
//初始化:A-1沒有考慮中間節點
for (i=0; i<n; ++i) {
for (j=0; j<n; j++) {
A[i][j] = MGraph[i][j];
path[i][j] = -1;
}
}
//迴圈考慮中間節點
for (v=0; v<n; ++v) {
for (i=0; i<n; ++i) {
for (j=0; j<n; ++j) {
if (A[i] [j]>A[i][v]+A[v][j]) {
A[i][j] = A[i][v] + A[v][j];
path[i][j] = v;
}
}
}
}
}
舉例:每一步執行
【工作原理】
完整程式碼
#include<stdio.h>
#include<stdlib.h>
#define maxSize 10
#define INF 100
int MGraph[maxSize][maxSize]; //鄰接矩陣
char vertexs[maxSize]; //結點資訊
void PrintPath(int u, int v, int path[][maxSize]) {
int mid;
if (path[u][v]==-1) {
//直接輸出,沒有中間點
printf("<%c,%c> ", vertexs[u], vertexs[v]);
} else { //有中間點
mid = path[u][v];
PrintPath(u, mid, path);
PrintPath(mid, v, path);
}
}
void Floyd(int n, int MGraph[][maxSize], int path[][maxSize]) {
int i,j,v;
int A[maxSize][maxSize]; //最短路徑
//初始化:A-1沒有考慮中間節點
for (i=0; i<n; ++i) {
for (j=0; j<n; j++) {
A[i][j] = MGraph[i][j];
path[i][j] = -1;
}
}
//迴圈考慮中間節點
for (v=0; v<n; ++v) {
for (i=0; i<n; ++i) {
for (j=0; j<n; ++j) {
if (A[i][j]>A[i][v]+A[v][j]) {
A[i][j] = A[i][v] + A[v][j];
path[i][j] = v;
}
}
}
}
}
int main() {
/*
7
ABCDEFG
10000 18 10000 10000 10000 19 18
18 10000 8 10000 10000 10000 20
10000 8 10000 20 10000 10000 10000
10000 10000 20 10000 9 16 15
10000 10000 10000 9 10000 3 10000
19 10000 10000 16 3 10000 15
18 20 10000 15 10000 15 10000
0 2
0 3
0 4
1 6
4 6
3 6
*/
int n;
int i,j;
char tmp[maxSize+5];
int path[maxSize][maxSize];
int start,end;
scanf("%d", &n); //結點數
scanf("%s", tmp); //結點資訊
for (i=0; i<n; i++)
vertexs[i] = tmp[i];
for (i=0; i<n; i++) { //矩陣
for (j=0; j<n; j++) {
scanf("%d", &MGraph[i][j]);
}
}
Floyd(n, MGraph, path);
//列印path陣列
printf("- path陣列\n");
printf("結點");
for (i=0; i<n; i++) {
printf("\t%c", vertexs[i]);
}
printf("\n");
for (i=0; i<n; i++) {
printf("%c\t", vertexs[i]);
for (j=0; j<n; j++) {
printf("%d\t", path[i][j]);
}
printf("\n");
}
//輸出最短路徑
while (1) {
printf("\n\n>>> 輸入起始點的下標(空格間隔):");
scanf("%d %d" , &start, &end); //輸入兩個測試的頂點,求v->w的最短路徑
printf("%c->%c最短路徑:", vertexs[start], vertexs[end]);
PrintPath(start, end, path);
}
return 0;
}