Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点到B,所以,我们假设dist(AB)为节点A到节点B的最短路径的距离,对于每一个节点K,我们检查dist(AK) + dist(KB) < dist(AB)是否成立,如果成立,证明从A到K再到B的路径比A直接到B的路径短,我们便设置 dist(AB) = dist(AK) + dist(KB),这样一来,当我们遍历完所有节点K,dist(AB)中记录的便是A到B的最短路径的距离。
// Floyd.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#define MaxVertexNum 100
#define INFINITY 65535
typedef int Vertex;
typedef char DataType;
typedef int WeightType;
typedef struct ENode *PtrToENode;
struct ENode {
Vertex V1, V2;
WeightType Weight;
};
typedef PtrToENode Edge;
typedef struct GNode *PtrToGNode;
struct GNode {
int Nv;
int Ne;
WeightType G[MaxVertexNum][MaxVertexNum];
DataType Data[MaxVertexNum];
};
typedef PtrToGNode MGraph;
MGraph CreateGraph(int VertexNum)
{
Vertex V, W;
MGraph Graph;
Graph = (MGraph)malloc(sizeof(struct GNode));
Graph->Nv = VertexNum;
Graph->Ne = 0;
for (V = 0; V<VertexNum; V++) {
for (W = 0; W<VertexNum; W++)
Graph->G[V][W] = INFINITY;
}
return Graph;
}
void InsertEdge(MGraph Graph, Edge E)
{
Graph->G[E->V1][E->V2] = E->Weight;
/*若为无向图,则还需要*/
//Graph->G[E->V2][E->V1] = E->Weight;
}
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
int Nv;
Vertex i;
printf("input the number of Vertex\n");
scanf_s("%d", &Nv);
Graph = CreateGraph(Nv);
scanf_s("%d", &Graph->Ne);
if (Graph->Ne != 0) {
E = (Edge)malloc(sizeof(struct ENode));
for (i = 0; i<Graph->Ne; i++) {
scanf_s("%d %d %d", &E->V1, &E->V2, &E->Weight);
InsertEdge(Graph, E);
}
}
return Graph;
}
void Floyd(MGraph Graph, int **D,int **path)
{
/*初始化有直接相连的两个结点的path,path为出发点*/
for(int i=0;i<Graph->Nv;i++)
for (int j = 0; j < Graph->Nv; j++) {
if (Graph->G[i][j] < INFINITY)
path[i][j] = i;
else
path[i][j] = -1;/*不相邻则默认无path*/
}
/*初始化D矩阵*/
for (int i = 0; i<Graph->Nv; i++)
for (int j = 0; j < Graph->Nv; j++) {
D[i][j] = Graph->G[i][j];
}
/*运算最短路径,每次从k开始,是因为每次开始都需要更新两个结点之间的dist,如果k放在后面循环,则会
过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了*/
int k, i, j;
for (k = 0; k < Graph->Nv; k++)
for (i = 0; i < Graph->Nv; i++)
for (j = 0; j < Graph->Nv; j++)
if (D[i][k] + D[k][j] < D[i][j]) {
D[i][j] = D[i][k] + D[k][j];
path[i][j] = k;
}
}
void printpath(int**path,int begin,int end)
{
while (path[begin][end] != begin) {
printf("%d ", path[begin][end]);
end = path[begin][end];
}
}
/*堆栈打印路径*/
/*
void printpath(int**path, int begin, int end)
{
if (path[begin][end] != begin) {
printpath(path, begin, path[begin][end]);
printf("%d", path[begin][end]);
}
else
printf("%d",begin);
}
*/
int main()
{
MGraph Graph;
Graph = BuildGraph();
int **D;
D = (int **)malloc(sizeof(int*)*Graph->Nv);
for (int i = 0; i < Graph->Nv; i++)
D[i] =(int*) malloc(sizeof(int)*Graph->Nv);
int **path = (int**)malloc(sizeof(int*)*Graph->Nv);
for (int i = 0; i < Graph->Nv; i++)
path[i] = (int *)malloc(sizeof(int)*Graph->Nv);
printf("Floyd begin\n");
Floyd(Graph, D,path);
printf("Floyd end\n");
printf("mindist\n");
for (int i = 0; i < Graph->Nv; i++)
for (int j = 0; j < Graph->Nv; j++)
printf("%d ", D[i][j]);
printf("\n");
printf("path\n");
for (int i = 0; i < Graph->Nv; i++)
for (int j = 0; j < Graph->Nv; j++)
printf("%d ", path[i][j]);
printf("printpath,input begin and end\n");
int begin, end;
scanf_s("%d %d", &begin, &end);
printpath(path, begin, end);
for(int i = 0;i<Graph->Nv;i++)
free(D[i]);
free(D);
for (int i = 0; i<Graph->Nv; i++)
free(path[i]);
free(path);
system("pause");
return 0;
}