最短路径问题:Floyd+Dijkstra算法

最短路径: Floyd+Dijkstra算法

1.问题

1 、用Floyd算法求解下图各个顶点的最短距离,给出距离矩阵。
在这里插入图片描述
2 、对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径。
在这里插入图片描述

2.解析

Floyd算法
原理:首先假设a(i)(j)是节点i到节点j的最短距离假设,然后对于每一个节点k,我们判断a(i,k) + a(k,j) < a(i,j)是否成立,若成立,则a(i,j) = a(i,k) + a(k,j),说明从i到k再到j的路径比i直接到j的路径短。当我们遍历完所有节点k,a(i,j)中记录的便是i到j的最短路径的距离。
算法描述:1.从任意一条单边路径开始,所有两点之间的距离是边的权值,如果两点之间没有边相连,则权为无穷大inf.若是自身到自身,则为0
2.设i,j两点间的最短距离为e(i,j),选中一个节点k,若a(i,k) + a(k,j) < a(i,j),则更新a(i,j) = a(i,k) + a(k,j),n个节点更新n次后完成。
初始距离矩阵为:
初始邻接矩阵
Dijkstra算法:
原理:该算法基于贪心算法,首先指定一个源点S,然后声明一个数组dis来保存源点到各个顶点的最短距离和数组map来保存已经找到了最短路径的顶点。通过select和slack两个操作不断更新源点S到点V的距离,select即选择操作,每次找到距离源点S最近并未被map数组标记的点,然后将其标记。slack即松弛操作,遍历select得到的点V所有的边,若存在dis[k]>dis[v]+map[v][k],则更新最短路径为经过点v的路径。最后得到的dis数组就是最短距离,若数组为无穷大,则说明无法到达。

3.设计

Floyd核心算法:

    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][j]=e[i][k]+e[k][j];

Dijkstra核心算法:

void Dijkstra(int v)
{
	memset(vis,0,sizeof(vis));
	for(int k=1;k<=n;k++)
	{
		dis[k]=map[v][k];
	}
	vis[v]=1;
	for(int k=1;k<n;k++)
	{
		int min=Inf,temp;
		for(int i=1;i<=n;i++)
		{
			if(!vis[i]&&dis[i]<min)
			{
				min=dis[i];
				temp=i;
			}
		}
		vis[temp]=1;
		for(int i=1;i<=n;i++)
		{
			if(map[temp][i]+dis[temp]<dis[i])
			{
				dis[i]=map[temp][i]+dis[temp];
			}
		}
	}
	
}

4.解析

Floyd算法:经过三层for循环,时间复杂度为O(n^3)
Dijkstra算法:对点集V进行选择操作,并对选择的点通过邻接矩阵进行相邻边的遍历操作,时间复杂度为O(n^2)

5.源码

Floyd算法
Dijkstra算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值