Floyd和Dijkstra的最短路

本文详细介绍了Floyd和Dijkstra两种最短路径算法的特点及应用。Floyd算法适用于求解任意两点间的最短路径,通过多次迭代优化路径长度;Dijkstra算法则专注于解决单源最短路径问题,逐步确定各点的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Floyd和Dijkstra的最短路问题

这两个算法都是用来求最短路径的算法,主要区别就是Floyd求的是任意两点之间的最短路值,Dijkstra主要求得是单源最短路,就是一个点到其他点的最短路值,二者都不能解决负权值问题。

弗洛伊德算法(Floyd算法)主要是用了一种“松弛”的方法,就是在从a到b的路线中是否能够找到一个中转点,比如说k点,就是dis[a][k]+dis[k][b]的值小于dis[a][b]的时候,可以从a出发先到k点,再转到b点,这样就可以达到题中最短的目的,然后以此类推。将已知所有点都作为中转点,进行一轮轮的比较。核心代码就只有5行,比较简单暴力。

for(k=1;k<=n;k++)//最外层的循环表示中转点的更新
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(e[i][j]>e[i][k]+e[k][j])//这里有一个稍难理解的一点,
//就是e[i][k],e[k][j]是经过之前几次中转后得到的最优解,所以可以中转几次的情况
				e[i][j]=e[i][k]+e[k][j];

迪杰斯特拉算法(Dijkstra算法)是求单源最短路的一个算法,核心代码也不多,主要一个思想就是找到确定的最短距离的点,然后对其他点进行松弛的处理,标记已知是最短距离的点,然后根据点的数量确定循环结束。

#include <stdio.h>
#include <string.h>
int e[10010][10010];
int dis[10010],book[10010];
int inf=99999999;

int main()
{
	int a,b,c,n,m;
	int i,j,k,u,s,min;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				if(i==j)
					e[i][j]=0;
				else
					e[i][j]=inf;
			}
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(c<e[a][b])//从一个地点到另外一个地点的路可能不止一条,只保存最短的一条这里有时候会坑 
				e[a][b]=c;	
		}
		memset(dis,0,sizeof(dis));
		memset(book,0,sizeof(book));
		for(i=1;i<=n;i++)
			dis[i]=e[1][i];//这里的源点是1点
		book[1]=1;
		for(s=1;s<n;s++)//循环n-1次,将除源点之外的n-1个点找出来
		{
			min=inf;//寻找距源点最近的未标记的点 
			for(i=1;i<=n;i++)
				if(book[i]==0&&dis[i]<min)
				{
					min=dis[i];
					u=i;
				}
			book[u]=1;
			for(k=1;k<=n;k++)//从确定距离源点最近的已知点出发,对每个点进行比较 
			{
				if(e[u][k]<inf)//确认两点之间是存在路径的
				{
					if(dis[k]>dis[u]+e[u][k])
						dis[k]=dis[u]+e[u][k];
				}
			}
		}
		for(i=1;i<=n;i++)
			printf("%d ",dis[i]);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值