最短路模板——SPFA(注意事项和易错点)
关于SPFA
SPFA一直以来给我的感觉就是一个玄学算法,尤其是时间复杂度,运气好是O(km),运气差是O(nm)。所以比赛的时候一定要使用最稳妥的算法——floyd或dijkstra。
以下是标准代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<iomanip>
#define MAX 999999999999999
#define N 10004
#define M 500005
using namespace std;
long long n,m,st,tot,head[N],edge[M],go[M],nxt[M],d[N];
bool v[N];
queue<long long> q;
long long read(){
long long x=0,h=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')h=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(long long)(ch-'0');ch=getchar();}
return x*h;
}
void add(long long x,long long y,long long z){
go[++tot]=y;edge[tot]=z;
nxt[tot]=head[x];head[x]=tot;
return ;
}
void spfa(){
memset(v,0,sizeof(v));
for(long long i=0;i<=n+2;i++)d[i]=MAX;
d[st]=0;v[st]=1;
q.push(st);
while(!q.empty()){
long long x=q.front(); q.pop();
v[x]=0;
for(long long i=head[x];i;i=nxt[i]){
long long y=go[i];
if(d[x]+edge[i]<d[y]){
d[y]=d[x]+edge[i];
if(!v[y]){
v[y]=1;q.push(y);
}
}
}
}
return ;
}
int main(){
n=read();m=read();st=read();
for(long long i=1;i<=m;i++){
long long x=read(),y=read(),z=read();
add(x,y,z);
}
spfa();
for(long long i=1;i<=n;i++){
if(d[i]==MAX)printf("2147483647 ");
else printf("%lld ",d[i]);
}
return 0;
}
对此代码来说,需要注意以下几点:
- 取出队头后
v[x]=0;必须加,不能忘记 if(!v[y])必须写在可以更新此点的if内
此代码以洛谷 P3371 【模板】单源最短路径(弱化版) 为模板

浙公网安备 33010602011771号