SPFA的优化一览

spfa,是一个早已没人用的算法,就像那些麻木的人,

可谁有知道,他何时槃涅

一个已死的算法 ,重生

内容

关于(NOI2018D1T1)的惨案,为了以防spfa被卡。

关于简单的(SLF)优化和(LLL)优化,再此不在多戍,算了,还是说说吧。

LLL 同样使用双端队列,维护目前队列中元素到起点的距离的平均值(即 (∑^{tail}_{i =head}dis[que[i]]/q.size())设该数为 k ,若 dis[now]>k ,则从队尾插入,否则从队首插入。

评:十分容易卡掉,加上一条权值巨大的边直接崩了

SLF 在使用queue作为spfa的辅助数据结构时,将队列替换为双端队列,每当插入元素 now 时,与队首进行比较,若 (dis[q.front()] > dis[now]),将 now从队首插入,否则从队尾插入。

评,这个算法,能让你,避免陷入求了很多次优解

这两个优化实际上没什么用,太过于与简单,稍微有心的出题人都会卡掉

我们再开看强一点的优化

容错后的SLF 定义容错值val,当满足 (dis[now]-val>=dis[q.front()])时从队尾插入,否则从队首插入。

评:我一般将val,定为-1,大了就没用了

在此就不用deque的*begin()了,实际实现时注意即好。

**MCFX ** 定义区间 [l,r] ,当入队节点的入队次数属于这个区间的时候,从队首插入,否则从队尾插入。

评:在某些毒瘤数据,真的很有用。

(这几个优化已经能过数据不刁钻的卡spfa的题,至于luogu的模板...fst qwq就是看着这几个优化来卡的...)

但是只要你val =-1 并且 加上MCFX,就能过了luogu的模板了

评:具体我也没有在网上找到,我说说自己理解的吧。容错SLF可以让你的程序不陷入局部最优解,与模拟退火类似;而mcfx优化是这样的,如过某个节点出发的大多数边都只能更新一个次解(说白了就是这个点如果是出题人用来故意让你经过多次的节点,并且每次更新会导致一次特别长的迭代,类似菊花图的根),那么它在队列中的优先级就会降低,就像你知道出题人用这个点来卡你,你竟然还把它最先拿来最先更新,肯定是不够好的。

至于 玄学优化,跳过好吗,我非

能不用 ,还是别用SPFA的,毕竟不要拿自己的命运做赌注

没有负权时,还是dijkstra吧

原文地址:https://www.cnblogs.com/zhltao/p/12252042.html