转山转水转回来——SPFA+++

   SPFA(Shortest Path Faster Algorithm)是一种经典的最短路算法。
   但因其效率的不稳定而常常处于尴尬的境地。。。(是那个出题人要装怪,不是我的错呀)
   这篇博客就是用来记录下其的优化。。。


SLF优化

设要加入的节点是j,队首元素为 i i ,若dis[j]<dis[i],则将 j j 插入队首,否则插入队尾;

bool SPFA(int s){
    for(int i=1;i<=n;i++)dis[i]=1e9;
    q.push_back(s);v[s]=1;dis[s]=0;
    while(!q.empty()){
        int x=q.front();
        q.pop_front();v[x]=0;
        for(int l=st[x];l;l=nxt[l])
        if(dis[ed[l]]>dis[x]+len[l]){
            dis[ed[l]]=dis[x]+len[l];
            if(!v[ed[l]]){
                if((++cnt[ed[l]])==n)return 1;
                if(!q.empty()&&dis[ed[l]]<dis[q.front()])
                q.push_front(ed[l]);
                else q.push_back(ed[l]);
                v[ed[l]]=1;
            }
        }
    }
    return 0;
}

负权回路的DFS优化

由于朴素的spfa判负权回路(根据入队次数)的复杂度是O(n2)的,不够优秀。。
于是一个“崭新”的方法就出现了:用DFS实现spfa,当同一条路径上有两个相同的点时,就可知出现负权回路了。

bool SPFA(int x){
    v[x]=1;bool b=0;
    for(int l=st[x];l;l=nxt[l])
    if(dis[ed[l]]>dis[x]+len[l]){
        if(v[ed[l]])return 1;
        dis[ed[l]]=dis[x]+len[l];
        b|=SPFA(ed[l]);
    }
    v[x]=0;
    return b;
}
···
int main(){
    ···
    for(int i=1;i<=n;i++)dis[i]=1e9;
    for(int i=1;i<=n;i++)f|=SPFA(i);
    ···
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值