SPFA 算法是Bellman-Ford算法的队列优化算法的别称,在国际上被称为“队列优化的Bellman-Ford算法”,仅在中国被称为SPFA算法。也就是说,这是Bell-man Ford的升级版(虽说本人也不会Bellman-Ford)。SPFA通常用于求含负权边的单源最短路径,以及判负权环。SPFA的时间复杂度一般为O(km)。但由于这种算法的过于玄学,当有人故意卡你时,可能会变成O(nm),所以请慎用。
例题
代码实现
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node
{
int ver;
int edge;
int next;
};
node d[100001];
queue <int> q;
int tot,x,y,z,dis[1001],head[100001],n,m;
bool v[100001];
void add(int a,int b,int c)//构建邻接表
{
tot++;
d[tot].ver=y;
d[tot].edge=z;
d[tot].next=head[x];
head[x]=tot;
}
void spfa()
{
memset(dis,0x3f3f3f,sizeof(dis));
memset(v,false,sizeof(v));
dis[1]=1;
v[1]=true;
q.push(1);
while(q.size())//每次取出队头
{
int x=q.front();
q.pop();
v[x]=false;//扫描所有边
for(int i=head[x];i;i=d[i].next)
{
int a=d[i].ver;
int b=d[i].edge;
if(dis[a]>dis[x]+b)//跟新最优解
{
dis[a]=dis[x]+b;
if(!v[a])
{
q.push(a);
v[a]=true;
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
spfa();
for(int i=2;i<=n;i++)
printf("%d\n",dis[i]-1);
return 0;
}
本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!
本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!
本次内容就到这里了,请各位朋友,有时间的给个赞,没时间的留个心,谢谢大家!