SPFA是求单元最短路径的算法,SPFA算法的全称是:Shortest Path Faster Algorithm。 SPFA算法是西南交通大学段凡丁于1994年发表的。SPFA可以计算有负边权的图,所以非常的万能。
SPFA的思想其实非常简单就是一种动态逼近,设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
松弛操作就是对于结点 i 寻找是否存在
若存在,就令
.。
如图: j 为起点 i 为终点,dis[i] = 6, dis[k] = 3,dis[i] > dis[k] + map[k][i]. 那么令 dis[i] = dis[k] + map[k][i].
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入队
}
}
}
}