SPFA算法(shortest path faster algorithm)算法是西南交通大学段凡丁于1994年发表的,它在Bellman-ford算法的基础上进行了改进,使其在能够处理待负权图的单元最短路径的基础上,时间复杂度大幅度降低。
算法核心:设立一个先进先出的队列用来保存待优化的节点,优化时每次取出队首节点u,并且用u点当前的最短路径估计值对离开u点所指向的节点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从从队列中取出节点进行松弛操作,直至队列空为止。
SPFA算法同样可以判断负环,如果某个点弹出队列的次数超过n-1次,则存在负环。对于存在负环的图,无法计算单源最短路径。
bool spfa()
{
int dis[maxn];
bool visit[maxn];
int queue[maxn];
int iq;
int top;
int outque[maxn];
for(int i=0;i<=n;i++){
dist[i]=inf;
}
memset(visit,0,sizeof(visit));
memset(outque,0,sizeof(outque));
iq=0;
queue[iq++]=s;
visit[s]=true;
dist[s]=0;
int headd=0;
while(headd!=iq){
top=queue[head];
visit[top]=false;
outque[top]++;
if(outque[top]>n){
return false;
}
int k=head[top];
while(k>=0){
if(dist[top]+edges[k].w<dist[edges[k].to]){
dist[edges[k].to]=dist[top]+edges[k].w;
if(!visit[edges[k].to]){
visit[edges[k].to]=true;
queue[iq++]=edges[k].to;
}
}
k=edges[k].next;
}
headd++;
}
return true;
}