关于Dijkstra求最长路

前言

今天下午训练赛有一题求最短路 和最长路的题,由于基础不够扎实,天真地以为改一下松弛操作、重载一下优先队列即可。事实上,经典Dijkstra并不能求最长路。

经典Dijkstra不能求最长路原理

在经典Dijkstra中,根据贪心思想,我们每次使用一个距离源点最短的点A来松弛其他点,并且保证了这个操作每个点只会进行一次,也即每个点有且仅有一次作为点A(除了距离最远的点,因为最后一点被松弛完整个算法就结束了)。

众所周知,迪杰斯特拉的使用条件是图中不存在负边。这是因为在不存在负边权的图中,最短路有子结构,子路径最短能保证总路径最短。根据这一性质,也有了一个结论,上面提到的用来松弛其他点的那个点A,距离源点的距离已经是最短的(这也是Dijsktra每个点只用来松弛一次的前提)。然而,以下两种情况不存在子结构:

  • 存在负边权,例如

在这里插入图片描述

  • 求最长路,例如

请添加图片描述

在不存在子结构的图中,一个点用来松弛其他点的点,未必已经是最优解。所以,我们可以使用允许多次松弛的算法(SPFA、经典Dijsktra改成允许一个点松弛其他点多次,事实上就应该称为SPFA了)来求最长路。

总结
  1. 正权边图中求最长路可使用SPFA
  2. 经典Dijsktra可在全负权边图中跑最长路、全正权边图中跑最短路
  3. Dijsktra+堆优化的时间复杂度为 O ( E l o g V ) O(ElogV) O(ElogV)、SPFA(Bellman Ford)+堆优化的时间复杂度是 O ( V E ) O(VE) O(VE)
  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值