浅谈最短路计数Dijkstra 与 SPFA实现的不同

本文探讨了Dijkstra和SPFA两种算法在计算最短路径计数时的区别。Dijkstra算法中,每个点只会对其他点最多松弛1次,而SPFA则可能需要额外的策略来确保正确性。通过举例说明,指出在SPFA中,当节点2的最短路径多次加到节点4上时,需要在松弛操作后清零当前队首的最短路径计数,以确保每次对其他点的修改为1。同时,文章提到了特殊情况下的处理方式,并提供了两种版本的算法代码实现。

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

由于Dijkstra每个点被“操作”完了后就不会再进行对其他点的松弛操作,而SPFA会入队多次,这就造成了它们在最短路计数实现上的不同

先说Dijkstra的思路,给每个点记一个ans[i]表示源点到当前点最短路的条数

若需要松弛,那么直接ans[y]=ans[x]

否则

Luogu

这个是非常好理解的,正确性也显然——每个点只会对其他点最多松弛1次。

而SPFA不能直接套用,一个显然的例子是

若直接套用会输出3。读者自行手玩一下就会发现,节点2的ans,多次加到了4身上。

那怎么改进呢?一种可行的方式是对于ans数组和now(当前队首),在now进行松弛操作后清零now的ans。

若从当前点now走最短路到对应点vis有三种方式,清零的意义就在于使得每次对vis产生的修改都是1,而不是1,2,2或1,2,3。

另外还需注意在

Luogu

这种情况下y也要入队,否则又会少加。(数据5 5 1 2 1 2 3 1 3 4 1 4 5 1 1 4 3)

两种版本的代码:

#include<bits/stdc++.h>
const int N=2005; 
con
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值