一看就懂,每对顶点间的最短路径- F算法

在这里插入图片描述

/*
2020/12/21 written by HL
所有端间最短径的算法
在某些情况下,要求找出图内所有两端间的最短径。当然,可以用D算法作n次运算,每次一个不同的端作为指定端。
弗洛埃德(Floyd)算法,简称F算法。
*/

#include<bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 100 //最大矩阵维度 
typedef struct MGRAPH
{
	int n;//图中顶点数目
	int e;//图中边的数目
	int vertex[MAX_VERTEX_NUM];
	int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
} MGraph;

MGraph* CreateMGraph( )
{
	MGraph *G=new MGraph ;
	int i,j,k,w;
	printf("请输入顶点数目和边的数目:");
	scanf("%d%d",&G->n,&G->e);
	//初始化邻接矩阵
	for(i=0; i<G->n; i++)
		for(j=0; j<G->n; j++)
			G->edge[i][j]=INT_MAX;
	printf("请输入%d条边和对应的权值:",G->e);
	for(k=0; k<G->e; k++)
	{
		scanf("%d%d%d",&i,&j,&w);//输入边的信息
		G->edge[i][j]=w;
		G->edge[j][i]=w;
	}
	return G;
}

//输出从顶点 v出发的所有最短路径

void Dispath(MGraph *G,int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM])
{
	int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
	int apath[MAX_VERTEX_NUM],d;//存放一条最短路径的中间顶点及其顶点个数
	int i,j,k,s;
	for(i=0; i<G->n; i++)
	{
		for(j=0; j<G->n; j++)
		{
			if(dist[i][j]!=INT_MAX &&i!=j)  //若Vi 到Vj 存在路径
			{
				printf("从%d到%d的路径为:",i,j);
				k=path[i][j];
				d=0;
				apath[d]=k;//路径上添加终点
				while(k!=-1 && k!=i ) //插入中间点 Vk
				{
					d++;
					apath[d]=k;
					k=path[i][k];
				}
				d++;
				apath[d]=i;//路径上添加起点 
				printf("%d",apath[d]);//输出起点 
				for(s=d-1; s>=0; s--)//输出路径上的中间顶点 
				{
					printf(",%d",apath[s]);
				}
				printf("\\t路径长度为:%d\n",dist[i][j]);
			}
		}
	}
}

//Floyd 算法 求解,每对顶点的最短路径
void Floyd(MGraph*G)
{
	int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
	int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
	int i,j,k;
	for(i=0; i<G->n; i++)
	{
		for(j=0; j<G->n; j++)
		{
			dist[i][j]=G->edge[i][j];
			if(i!=j && G->edge[i][j]<INT_MAX)
				path[i][j]=i;    //Vi 到Vj 有边
			else    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(dist[i][j]>dist[i][k]+dist[k][j])
				{
					dist[i][j]=dist[i][k]+dist[k][j];
					path[i][j]=path[k][j];
				}
			}
		}
	}
	Dispath(G,dist);
}

int main()
{
	MGraph *G=CreateMGraph();
	Floyd(G);
	system("pause");
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值