弗洛伊德算法求出最短路径

来源:互联网 发布:淘宝直播在哪里可以看 编辑:程序博客网 时间:2024/06/09 16:32
#include<stdio.h>
#include<stdlib.h>
typedef int Edgetype;//存储边的关系 
typedef  char VerType;//定点类型应由用户定义
#define MAXVER 100
#define INFINITY 66235
typedef struct {
VerType ver[MAXVER];
Edgetype edeget[MAXVER][MAXVER];
int numVertexes,numEdges;//输入当前的节点数,与边书 
}MGraph;


MGraph creatGraph();
void MiniSpaTree(MGraph G); 
int find(int parent[],int f);
//void Dijkstra(int p[],int d[],int v0,MGraph G); 
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER],MGraph G);
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER],MGraph G,int v0,int v1);
int main(){
MGraph G = creatGraph();
int p[MAXVER][MAXVER],d[MAXVER][MAXVER],v0 = 0;
Floyd_dis(p,d,G);
//printf("%d",d[2]);
show(p,d,G,0,3);
return 0;

MGraph creatGraph()
{
int i,j,k,w;
MGraph G;
printf("请输入节点总数,与边的总数");
scanf("%d%d",&G.numVertexes,&G.numEdges);
getchar();
for(i=0;i<G.numVertexes;i++)
{
printf("请输入第%d个节点的数据",i+1);
scanf("%c",&G.ver[i]);
// printf("%c",G.ver[i]); 
getchar();
}

//设置个边的关系
for(i=0;i<G.numEdges;i++)
{
for(j=0;j<G.numEdges;j++)
{
if(i==j)
G.edeget[i][j]=0;
else
G.edeget[i][j] = INFINITY;

}
//printf("dafg");
for(k=0;k<G.numEdges;k++)
{
printf("请输入vi,vj边上的序号:");
scanf("%d%d",&i,&j);
printf("请输入权值"); 
scanf("%d",&w);
G.edeget[i][j]= w;
G.edeget[j][i] = w;
}
return G; 
}
/*
根据弗洛伊德算法求最短路径,、
思路: 相当于一五边形分割成了多个三角形
详情:http://blog.csdn.net/zhongkeli/article/details/8832946 
定义了两个二维数组,p[][]用p来存储每次改变路径是的中间点(也就是所谓的前驱矩阵)
d[]是用来存储当前已经求得某些点的最短距离,所以要利用for语句将所有点都遍历一到
*/
//---------------------------------------------------------------------
/*
弗洛伊德算法虽然时间复杂度为n^3,但是它可以一次性将 搞出所有点到其他任意一点的最短距离 
优雅而又简洁 
*/ 
void Floyd_dis(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER],MGraph G)
{
for(int i=0;i<G.numVertexes;i++)//初始化p,d 
{
for(int j=0;j<G.numVertexes;j++)
{
d[i][j] = G.edeget[i][j];
p[i][j] = j;
}

for(int i=0;i<G.numVertexes;i++)//作为传说中的中间点 
{
for(int j=0;j<G.numVertexes;j++)
{
for(int k=0;k<G.numVertexes;k++)
{
if(d[j][k] > (d[j][i]+d[i][k]))//有点像向量的加减
{
d[j][k] = d[j][i]+d[i][k];
//因为最后还是要遍历d[k][j]的所以无需管d[k][j]
p[j][k] = P[j][i];  //p[j][k]代表的是前驱
//因为j-k的路径不一定是直接存在的也可能用通过j的前驱找出来的
//所以p[j][k]不能存点的中间点的位置,而是应该存的是到中间的前驱
 

}
}
}
}
void show(int p[MAXVER][MAXVER],int d[MAXVER][MAXVER],MGraph G,int v0,int v1)
{
char c= G.ver[v0];
//printf("%c ->",c);
int k = v0; 
printf("The shortest distance = %d\n",d[v0][v1]);

//printf("%c ->",c);
while(k!=v1)
{
printf("%c ->",c);
k = p[k][v1];
// printf("%d",k); 
c = G.ver[k];

printf("%c",c) ;

}


测试数据:0 1 1 1 3 7 3 6 3 6 8 7 8 7 4 7 5 5 5 2 7 2 0 5 1 2 3 6 7 2 3 4 2 6 4 6 7 4 9 5 4 3 2 4 1


0 0
原创粉丝点击