图--最短路径--弗洛伊德算法

算法基本思想:
1、初始化两个二维数组D[][]和P[][],D[v][w]用于表示从顶点v到顶点w的最小权和,P[v][w]表示从顶点v到顶点w需要经过顶点P[v][w],D[][]初始值为邻接矩阵,P[][]初始值为列下标;
2、遍历所有的顶点k,每个顶点又遍历D[][]中的每一个元素D[v][w],若经过v经过k到达w的路径比原先的路径短的话,将当前两点间的权值设为更小的一个,同时将P[v][w]值置为P[v][k];
3、最后要得到从v点到w点的路径为:v->P[v][w]->P[P[v][w]][w]...->e
#include <stdio.h>
#define MAXVEX 9
#define INFINITY 65535
typedef int Pathmatirx[MAXVEX][MAXVEX];		//用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVEX][MAXVEX];	//用于存储到各点最短路径的权值和

typedef struct MGraph
{
	int numVertexes;
	int arc[9][9];
}MGraph;

void floyd(MGraph G,Pathmatirx *P,ShortPathTable *D)
{
	int v,w,k;
	for(v=0;v<G.numVertexes;++v)	//初始化D与P
	{
		for(w=0;w<G.numVertexes;++w)
		{
			(*D)[v][w]=G.arc[v][w];	//D[v][w]值即为对应点间的值
			(*P)[v][w]=w;
		}
	}
	for(k=0;k<G.numVertexes;++k)
	{
		for(v=0;v<G.numVertexes;++v)
		{
			for(w=0;w<G.numVertexes;++w)
			{	//如果经过k顶点路径比原来两点间路径更短,更新
				if((*D)[v][w]>(*D)[v][k]+(*D)[k][w])
				{
					(*D)[v][w]=(*D)[v][k]+(*D)[k][w];
					(*P)[v][w]=(*P)[v][k];	//路径设置经过下标为k的顶点
				}
			}
		}
	}
}

void main(void)
{
	int i,j,k,b,e;
	MGraph G=	//顶点数和权值表(行下标对应顶点到列下标对应顶点的边权值)
	{
		/*.numVertexes=*/9,	//结构体初始化搞半天原来是VC不支持C99标准
		/*.arc[9][9]=*/{0,1,5,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,
			        1,0,3,7,5,INFINITY,INFINITY,INFINITY,INFINITY,
					5,3,0,INFINITY,1,7,INFINITY,INFINITY,INFINITY,
					INFINITY,7,INFINITY,0,2,INFINITY,3,INFINITY,INFINITY,
				    INFINITY,5,1,2,0,3,6,9,INFINITY,
					INFINITY,INFINITY,7,INFINITY,3,0,INFINITY,5,INFINITY,
					INFINITY,INFINITY,INFINITY,3,6,INFINITY,0,2,7,
					INFINITY,INFINITY,INFINITY,INFINITY,9,5,2,0,4,
					INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,7,4,0,},
	};
	Pathmatirx P;
	ShortPathTable D;
	/*printf("Enter the number of Vertexes:");
	scanf("%d",&G.numVertexes);
	for(i=0;i<G.numVertexes;++i)
	{
		for(j=0;j<G.numVertexes;++j)
		{
			scanf("%d",&G.arc[i][j]);
		}
	}*/
	floyd(G,&P,&D);
	printf("begin:");
	scanf("%d",&b);
	printf("end:");
	scanf("%d",&e);
	printf("weight:%d\n",D[b][e]);
	printf("%d",b);
	for(i=0;i<G.numVertexes;++i)
	{
		b=P[b][e];
		printf("->%d",b);
		if(b == e)
			break;
	}
}
算法时间复杂度为O(n^3)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值