对于SPFA的两个小优化

SPFA对于稀疏图非常的有用,然而对于稠密图就是辣鸡。。(还是很厉害的)。

稠密图可以使用dij,但是SPFA真的败给了稠密图了吗?

答案是不是的,优化强着呢,杠杠滴~

优化一:SLF

怎么做呢?

假设我们当前在跑SPFA的最短路(下面都是)。

设我们的队头为i,要加进去队列的数为j,那么我们就可以根据最短路,加出如下优化

若dis[j]<dis[i],那么j加进队列的开头,反之,加入队尾

为什么呢?因为j比i更有可能是最短路的一个点,所以我们先进行如何?

实现怎么弄?

因为head=1必定不可能进行如上情况

只有head>1才有如上情况

我们先把head-2,因为当前队头为head,下一次+1就到了head-1了

然后j放在head-1上

if dis[b[x,i]]<dis[d[head]] then
                                begin
                                        dec(head,2);
                                        d[head+1]:=b[x,i];
                                end
                                else
                                begin
                                        inc(tail);
                                        d[tail]:=b[x,i];
                                end;

优化20%左右

优化二LLL:

我们可以算出所有队列(head~tail))的元素的dis值的和,然后求出平均数

如果当前的队头i的dis值比这个平均值大,也就是说,后面有存在比这个点更加有可能为最短路的值

那么把队头的数放到队尾

每次如此,知道有一个小于等于平均值

inc(head);
                ans:=0;
                for i:=head to tail do
                        ans:=ans+dis[d[i]];
                ans:=ans/(tail-head+1);
                while dis[d[head]]>ans do
                begin
                        inc(tail);
                        d[tail]:=d[head];
                        inc(head);
                end;
                x:=d[head];//后面继续进行SPFA
这些优化很强势

我的一个8s的程序,是pas的

瞬间到100ms

猜你喜欢

转载自blog.csdn.net/fengyingjie2/article/details/54619585