最快的最短路——SPFA!

 

SPFA是求单元最短路径的算法,SPFA算法的全称是:Shortest Path Faster Algorithm。  SPFA算法是西南交通大学段凡丁于1994年发表的。SPFA可以计算有负边权的图,所以非常的万能。

SPFA的思想其实非常简单就是一种动态逼近,设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

松弛操作就是对于结点 i 寻找是否存在dis[j]+map[i][j]< dis[i] dis[j] + map[i][j] < dis[i] 若存在,就令 dis[i] = dis[j] + map[i][j].。

如图: j 为起点 i 为终点,dis[i] = 6, dis[k] = 3,dis[i] > dis[k] + map[k][i]. 那么令 dis[i] = dis[k] + map[k][i].

 

最快的最短路——SPFA!_第1张图片

void spfa(x)
{
	for i 1->n//初始化
	{
		dis[i] = INF;
	}
	dis[x] = 0;//起点花费为0
	q.push(x);//起点入队
    vis[x] = true;
	while(q.empty())//若队列不为空
	{
		int u = q.top();//取出队首
		q.pop();//删除队首
        if(vis[u])continue;//如果走过
		vis[u] = 1;//如果没走过 把队首标记
		for (枚举所有边)
			if(dis[i] > dis[v] + map[v][i])
			{
				dis[i] = dis[v] + map[v][i];//松弛操作
				if(vis[i] = false) //如果没走过
				{
					vis[i] = true;//标记
					q.push(i);//将i入队
				}
			 } 
	}
}

 

你可能感兴趣的:(图论)