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;
}