Shortest Path Faster Algorithm(SPFA)算法
其实是BFS宽度优先搜索,利用队列进行优化
可以解决带有负边权的单源最短路问题,另外可以用来判断负环
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define MAX 0x3f3f3f3f
#define N 100005
//定义边
typedef struct edge {
int re;//弧尾
int w;//边权
};
//n为点个数,m为边的个数,dst保存最短距离
int n, m, dst[N];
vector<edge> a[N];//邻接表
bool flag[N];//标记数组
void spfa()
{
memset(dst, 0x3f, sizeof dst);//dst初始化为MAX
dst[1] = 0;//1为起始结点
queue<int> q;
q.push(1);//将当前结点入队
flag[1] = true;//标记,表示队列中已经有该结点
while (!q.empty())
{
int j = q.front();
q.pop();//队头出队
flag[j] = false;
for (int i = 0; i < a[j].size(); i++)
{
//遍历与j相连的所有边
if (dst[a[j][i].re] > dst[j] + a[j][i].w)
{
//如果能使到达相连结点的最短距离变短,则更新距离
dst[a[j][i].re] = dst[j] + a[j][i].w;
if (!flag[a[j][i].re])
{
//如果相连的结点不在队列中
q.push(a[j][i].re);
//将该相连且使得最短距离发生变化的结点入队
flag[a[j][i].re] = true;
}
}
}
}
}
int main()
{
int num1, num2, num3;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++)
{
scanf("%d %d %d", &num1, &num2, &num3);
edge e;
e.re = num2;
e.w = num3;
a[num1].push_back(e);//有向图
}
spfa();//函数调用
if (dst[n] == MAX) printf("impossible");//输出不可达
else printf("%d", dst[n]);//输出从1到n的最短距离
return 0;
}