算法笔记(9):floyd算法和dij算法的比较

本文对比了Floyd算法与Dijkstra算法在队列优化中的关键区别,指出Floyd允许多次入队优化负权边,而Dijkstra仅依赖于起点最近节点。通过实例解析,解释了为何两者结果一致,强调了队列优化策略在算法中的作用。
摘要由CSDN通过智能技术生成

今天发现两算法用队列优化时表现出许多相似性,而且队列优化思想与未优化的思想有所不同,容易产生误解,故总结一下

Floyd算法核心
for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (dis[i][j] > dis[i][k] + dis[k][j])
                dis[i][j] = dis[i][k] + dis[k][j];

循环过程,k是中转点,故核心思想为从只能通过1中转,只能通过1,2中转……只能通过1,2,3……n中转。

队列优化的代码在之前的文章中已经给出,这里对比一下两者的不同。

观察很容易发现这里通过k点中转,dis[k][j] 可以使k经过其他中转点(1,2,3……k-1)到达j对应的距离,即k->……->j;
而在队列优化代码中,比较的是 dis[u][v]>dis[u][id]+w[i](此处id是中转点),其中w[i]是指id->v的距离,并且中间不会经过中转点
两者的差异是否会造成结果错误呢?
答案是不会的,考虑这样一个过程
在这里插入图片描述

在不用队列的算法中,首先经过1中转可以减少到4的距离,一轮循环后,中转点变成2,在上一轮循环中,2->4也被优化为2->1->4,此时的dis[2][4]显然已经不是2直接到4的距离了,之后再次优化dis[3][4],得最下图所示路径;下面我们看一下用队列优化会有什么效果。

首先在第一轮中,3->43->13->2的距离发生改变,故节点142入队(这里4出队与结果无关,故不考虑4)。情况一:1先出队,根据出边优化得3->1->4,之后2出队,出边继续优化发现3->1可以优化为3->2->1,此时节点3到节点1的距离再次发生改变,故节点1又入队,再出队后边优化到了图中最后一步的情况。情况二更好考虑,故不再赘述。

比较队列优化没有bug的原因,队列优化能通过节点的重复入队,来不断优化两点间的距离,故尽管出边优化过程中出边的到终点的距离都是没有经过中转点的,其仍然可以得到正确结果。

dij算法核心

每次找到距离起点最近的估计值的点,设为确定值,并将其作为中转点优化起点到其他点的距离。
找最近的过程可以用优化,即优先队列。

可以发现两者使用队列的方式是十分相似的,都是用在队列中的节点的出边来优化,但是不同之处在于,dij算法中出队的永远都是队中距离起点最近的,并且每个节点只会入队一次,而Floyd算法每个节点可以入队多次,并无需确保出队节点距离起点的远近,这决定了Floyd算法可以处理负权边,而dij不行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值