1. 程式人生 > >[圖] 6.3.1 Floyd演算法|佛洛依德

[圖] 6.3.1 Floyd演算法|佛洛依德

文章目錄

測試資料

結果

在這裡插入圖片描述

實現

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; }