~SPFA算得上是bellman-ford算法优化,采用的是动态逼近的方法,对dist数组进行一次次的更新,最后得出最终的最短路径。再捎带说一点Dijkstra与SPFA的适用情况以及一些不同之处。
- Dijkstra是每次确定了到一个点的最短距离,再用该点更新到其它点的距离。不能处理有负边的图。
- Bellman-Ford是每次对所有边松弛。可以计算出有负边无负环的最短路,可以判断是否存在负环。
使用邻接矩阵的SPFA算法模板:
#include <iostream>
#include <queue>
#include <climits>
using namespace std;
int gra[100][100];
int dist[103];
bool vis[100];
void spfa(int n) //借助队列优化,本质上是动态逼近,最后求出最终的最短路径
{
memset(vis, false, sizeof(vis));
for(int i = 1; i <= n; i++)
{
dist[i] = INT_MAX;
}
queue < int > q;
q.push(1);
vis[1] = true;
dist[1] = 0;
while(!q.empty())
{
int s = q.front();
q.pop();
vis[s] = false; //确保该点还有机会入队列
for(int i = 1; i <= n; i++)
{
if(dist[i] > dist[s] + gra[s][i]) //可以对所有的点更新,包括已经标记为访问过的点
{
dist[i] = dist[s] + gra[s][i];
if(!vis[i]) //如果没有被访问过,也就是没有在队列里面的话就加入其中,用该点去更新其他点
{
q.push(i);
vis[i] = true;
}
}
}
}
}
int main()
{
return 0;
}