卡spfa的一些方法&&对spfa的一些深入理解

  知己知彼,百战不殆

  spfa队头元素不一定是队内最优最应该先出队的元素,出队顺序全看入队顺序。

  整理了一些常见的卡spfa方法及见招拆招的针对性优化。

   卡spfa的关键依据:贪心的松弛操作、每次更新节点时更新所有出边,(偶尔)负权边

  核心:诱导贪心的spfa不断更新次短路,多次更新与该点相连的部分。

  常见卡spfa用图(可以在所有普通图上外挂,加以诱导节点;甚至互相搭配):

    链套菊花图(链上负权边,会多次更新非链的菊花图的另一半)、网格图(竖边权为0或很小(万恶之源),使很多长度不同的路径权值和相近,那么一次找到最短路的概率就小得多,就有可能多找了几条次短路,多更新了几次同一个点)   

      ——笔记」如何优雅地卡 Spfa

    

  见招拆招:

    1、随机取点:每次从队列取队头前,先把队头与队内随机一个元素交换(数组模拟队列会非常方便这种操作);

    2、随机出边:当前点出队时,将出边暂存,以随机顺序访问;

    (1 2 有效克制菊花图)

    ……

    如何看待 SPFA 算法已死这种说法? - fstqwq 的回答 - 知乎

    如何卡spfa? - Raffica的回答 - 知乎 https://www.zhihu.com/question/268382638/answer/337778164 

     给spfa加堆优化:时间复杂度O(kMlogM) 点u入堆时要注意不管u在不在堆里,都要入堆;或实现堆内元素修改操作(先删了队里的u再入堆加上当前的u),这样logM能变logN,但常数更大。可能在很个别的时候会用到。

后记:

  (段凡丁曾经证明 SPFASPFA 的时间复杂度是 O(ke)O(ke)(kk 是小常数),但是他的证明已经被证明是错误的,请大家注意)

posted @ 2021-08-17 15:30  千叶繁华  阅读(506)  评论(0编辑  收藏  举报