Roads and route optimization algorithm [spfa + slf metaphysics optimization] []

Topic Link

题意:给定负权图,输出源点到个点的最短路
思路:spfa算法
玄学优化:对于SPFA算法而言,它的优化有两种,我们今天使用SLF优化算法.

众所周知,SPFA算法是一种鉴于队列的实现算法
每一次有节点加入队列都是加入队尾.

但是SLF优化,不同于一般的SPFA算法,
它是一种利用双端队列算法处理的问题.

如果说当前点所花费的值少于我们当前队头点的值的话,
那么我们就将这个节点插入到队头去,否则我们还是插入到队尾.

这个就是非常好用的SLF优化算法.
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<deque>

using namespace std;
const int N=4*50000+10;
int h[N],ne[N],e[N],w[N],idx;
int t,r,p,s;
int dis[N];
bool st[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}


void spfa()
{
    memset(dis,0x3f,sizeof dis);
    memset(st,false,sizeof st);
    dis[s]=0;
    deque<int> q;
    q.push_back(s);
    st[s]=true;

    while(q.size())
    {

        int t=q.front();
        q.pop_front();
        st[t]=false;
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];

            if(dis[j]>dis[t]+w[i])
            {
                dis[j]=dis[t]+w[i];
                if(!st[j])
                {

                    st[j]=true;
                    if(!q.empty() && dis[j]<dis[q.front()])
                    {
                        q.push_front(j);

                    }
                    else
                    {
                        q.push_back(j);

                    }

                }

            }
        }
    }
}

int main()
{
   
    memset(h,-1,sizeof h);

    t=read();
    r=read();
    p=read();
    s=read();
    while(r--)
    {
        int a,b,c;
        a=read(),b=read(),c=read();

        add(a,b,c);
        add(b,a,c);
    }
    while(p--)
    {
        int a,b,c;
        a=read(),b=read(),c=read();

        add(a,b,c);
    }

    spfa();
    for(int i=1;i<=t;i++)
    {
        if(dis[i]>0x3f3f3f3f/2)
            cout<<"NO PATH"<<endl;
        else cout<<dis[i]<<endl;
    }
    return 0;
}

Published 152 original articles · won praise 4 · Views 3895

Guess you like

Origin blog.csdn.net/qq_43716912/article/details/100093442