Floyd算法与Dijstra的区别在于Floyd计算的是任意两点间的最短路径。
可以这样思考,首先是各点都不允许借路通过,然后依次从第一个点到最后一个点均允许借路通过,每次均取最短路,则到最后求得的就是各个点的最短路。
状态转移公式为Dk(i,j)=min(Dk-1(i,j),Dk-1(i,k)+Dk-1(k,j));
测试样例
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
#define MaxVertexNum 100
#define INF 32767
typedef struct
{
char vertex[MaxVertexNum];
int edges[MaxVertexNum][MaxVertexNum];
int n,e;
}MGraph;
void CreateMGraph(MGraph &G)
{
int i,j,k,p;
cout << "请输入顶点数和边数:";
cin >> G.n >> G.e;
cout << "请输入顶点元素:";
for(i = 0;i < G.n;i++)
cin >> G.vertex[i];
for(i = 0;i < G.n;i++)
for(j = 0;j < G.n;j++)
{
G.edges[i][j] = INF;
if(i == j)
G.edges[i][j] = 0;
}
for(k = 0;k < G.e;k++)
{
cout << "请输入第" << k+1 << "条弧头弧尾序号和相应的权值:";
cin >> i >> j >> p;
G.edges[i][j] = p;
}
}
void Ppath(MGraph &G,int path[][MaxVertexNum],int i,int j)
{
int k;
k = path[i][j];
if (k == -1)
return;
Ppath(G,path,i,k);
printf("%c",G.vertex[k]);
Ppath(G,path,k,j);
}
void Dispath(MGraph &G,int A[][MaxVertexNum],int path[][MaxVertexNum],int n)
{
int i,j;
for(i = 0;i < n;i++)
for(j = 0;j < n;j++)
{
if(A[i][j] == INF)
{
if(i != j)
printf("从%d到%d没有路径\n",i,j);
}
else
{
printf("从%c到%c=>路径长度:%d 路径:",G.vertex[i],G.vertex[j],A[i][j]);
printf("%c",G.vertex[i]);
Ppath(G,path,i,j);
printf("%c\n",G.vertex[j]);
}
}
}
void Floyd(MGraph &G)
{
int i,j,k;
int A[MaxVertexNum][MaxVertexNum];
int path[MaxVertexNum][MaxVertexNum];
for(i = 0;i < G.n;i++)
for(j = 0;j < G.n;j++)
{
A[i][j] = G.edges[i][j];
path[i][j] = -1;
}
for(k = 0;k < G.n;k++)
for(i = 0;i < G.n;i++)
for(j = 0;j < G.n;j++)
if(A[i][j] > A[i][k] + A[k][j])
{
A[i][j] = A[i][k] + A[k][j];
path[i][j] = k;
}
Dispath(G,A,path,G.n);
}
int main()
{
MGraph G;
CreateMGraph(G);
Floyd(G);
return 0;
}
运行结果: