SPFA算法
求单源最短路的SPFA算法的全称是:Shortest Path Faster
Algorithm。 最短路径快速算法-SPFA算法是西南交通大学段凡丁于1994年发表的。
适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点。
算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
标程一:
const
int INF =
999999;
int
map [MAXN][MAXN];
//map[i,j]为初始输入的i到j的距离,未知的map[i,j]=INF;
int
dis [MAXN];//源点S到i的最短路
char vst[MAXN];//是否在队列中的标记
int
Q[MAXN]; //队列
//
参数n表示结点数,s表示源点
int SPFA(int n,
int s)
{ int
i, pri, end, p, t;
// pri是队列头结点,end是队列尾结点
Q[0] =
s;//源点入队
pri = 0; end
= 1;//队首队尾赋值
}
标程二:
int num[999999]; //记录入队次数
void spfa(int s) //
初始结点s,即为起点,若目标结点t,则输出dict[t]。
{
init_data(s);
}
判断负权回路
num[i]>=n的原因,即使所有的点更新都会让i入队的话,才只有n-1次,这时一定是最小值了,入队n次,一定有负权回路