SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。(百度百科)SPFA算法由Fanding Duan于1994年在西南交通大学学报上发表。
算法思想:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
Reference:WIKIPEDIA
最短路径算法更快(SPFA)是的改进Bellman-Ford算法,其计算在加权有向图的单源最短路径。该算法被认为在随机稀疏图上运行良好,特别适用于包含负权边的图。[1]然而,SPFA的最坏情况复杂度与Bellman-Ford相同,因此对于具有非负边权的图,Dijkstra算法是首选。[2] SPFA算法由Fanding Duan于1994年在西南交通大学学报上发表。
贴下代码:
bool SPFA()
{
int u;//从队列中取出的数
int i;
queue<int>que;
int dist[503];//保存在短距离
bool vis[503];//访问数组
int flag[503];//记录点进入队列的次数。
memset(flag,0,sizeof(flag));
memset(vis,false,sizeof(vis));
fill(dist,dist+n+1,MAX);//将dist[]数组初始化为最大值
dist[1]=0;
que.push(1);//将1放入队列
while(!que.empty())//不为空
{
u=que.front();//取出第一个数
que.pop();//删除此数
viu[u]=false;//标记为未访问过
for(i=1;i<=n;i++)//所有边
{
if(dist[i]>dist[u]+G[u][i])//进行松弛计算
{
dist[i]=dist[u]+G[u][i];//成功
if(!vis[i])
{
vis[i]=true;
flag[i]++;//入队次数+1
if(flag[i]>=n)//若此点进入队列超过N次,证明有负环
return true;
que.push(i);//此点放入队列
}
}
}
}
return false;//没有负环
}
fill函数的作用是:将一个区间的元素都赋予val值。
函数参数:fill(first,last,val);//first为容器的首迭代器,last为容器的末迭代器,val为将要替换的值。