五种最短路径算法的总结(待更新)

最短路径算法:

         1:Dijkstra     2:Floyd     3:Bellman-Ford     4:SPFA     5:A*

这五种最短路径算法初学的时候非常容易混淆,因为他们的松弛方法都差不多,而他们的核心却又与松弛有着很密切的关系,所以很难去辨别区别。

1:Dijkstra

Dijkstra算法适用于单源最短路,也就是从一个点到终点,过程比较贪心,逻辑上是寻求最近点来逐步拓展,以达到局部最优的效果,再由局部最优一一推出全局最优

实现过程:建立dist数组存与原点的距离

1:从全部点中找离确定点(一开始是初始点)最近的点。

2:找到后将它设置为确定点(第二次查找就从他开始了)

3:全局搜索现在这个确定点能扩展到的所有点(也就是与确定点相连的点)(判断能否连通了可以用e[i][j]<inf来判断)

4:松弛操作:看看由原点直达这个点近还是经过确定点近

dist[v]>dist[u]+e[u][v]

5:能扩展就扩展,扩展完后这个点的dist就是到原点的最短距离

6:那么扩展到dist[n]的话,最短距离就是dist[n]

整体思想:找最近点将它们达到的点逐步扩展,更新他们到原点的最短距离。

代码链接:(精简代码+堆优化)

https://blog.csdn.net/Syclus/article/details/123093141?spm=1001.2014.3001.5501

代码:二维存数版本

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;

int main()
{
	int e[10][10],dis[10],book[10],n,m,t1,t2,t3,u,v,min;
	int inf=99999999;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)//初始化过程 
		{
			if(i==j)//对角线为0(与自身的距离=0) 
				e[i][j]=0;
			else
				e[i][j]=inf;
		}
	} 
	for(int i=1;i<=m;i++)
	{
		cin>>t1>>t2>>t3;
		e[t1][t2]=t3; 
	} 
	for(int i=1;i<=n;i++)//初始化dis,与1的距离 
		dis[i]=e[1][i];
	memset(book,0,sizeof book);//看看当前位置有没有被确定 
	book[1]=1;//1点开始走当然确定了 
	for(int i=1;i<=n-1;i++)//大循环为n-1次,就一计数的 
	{//更新n-1个点所以才这样 
		min=inf;
		for(int j=1;j<=n;j++)//找最近点 
		{
			if(book[j]==0 && dis[j]<min)//走过就不用了 
			{
				min=dis[j];
				u=j;
			}
		} 
		book[u]=1;//确定最近点
		for(v=1;v<=n;v++)
		{
			if(e[u][v]<inf)//能联通
			{
				if(dis[v]>dis[u]+e[u][v])
					dis[v]=dis[u]+e[u][v];
			} 
		} 
	} 
	for(int i=1;i<=n;i++)
		cout<<dis[i]<<" ";
	cout<<endl;
	return 0;
 } 
 
 
 
 

2:Floyd(自由:任意两点最短路、过前几个点求最短路)

Floyd算法适用于多源最短路问题,求的是任意两个点的最短路问题,注重的是这个最短路径有没有考虑到所有点,总共三层循环On3,内两层循环统计只考虑过一点的话任意两点之间的最短路(i,j之间最短的距离),最外层循环过k点。这个完全可以根据需求来定,想过几点求最短路,或者哪一点到哪一点都可以。

代码:

for(int k=1;k<=n;k++)//记住是先算只允许经过1点更新完后,再更新只经过2点
{//所以一遍一遍更新下来,最短路会越来越完善
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(e[i][j]>e[i][k]+e[k][j])//过k点的话可不可以优化
                e[i][j]=e[i][k]+e[k][j];
        }
    }
}

3:Bellman-Ford算法:(有负权边)

算法思路:

1.迭代n次(假设迭代了k次,含义:从1号点,走不超过k条边到达所有点的最短距离)

2.每次循环所有边,for(所有边 a,b,w)

3.每次松弛操作:dist[b]=min(dist[b],dist[a]+w)

(可以保证三角不等式,每一个dist[b]<dist[a]+w)

(遇到有边数限制的题目,用backup数组备份一下上次的迭代结果,防止数据串联)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值