SPFA算法 (基于Bellman-Ford算法)

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为将要替换的值。

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/JYL1159131237/article/details/78567075
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞