上一篇文章对Bellman-Ford算法的一种优化是每次仅对最短路程发生了变化的点的相邻边执行优化操作。这里可以用队列来维护这些点
#include<iostream>
using namespace std;
int main() {
int m, n;
int u[8], v[8], w[8]; //数组大小要比m的最大值大1
int first[6], next[8];//first比n大1,next比m大1
int dis[6] = { 0 }, book[6] = { 0 };//book记录哪些顶点在队列中
int que[101] = { 0 }, head = 1, tail = 1;//定义队列
int inf = 99999999;//无穷大
cout << "输入顶点数和边的条数" << endl;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
dis[i] = inf;//初始化dis,是1号顶点到其余个顶点的路程
book[i] = 0;//刚开始都不在队列中
first[i] = -1;//-1表示刚开始暂时都没有边
}
dis[1] = 0;
for (int i = 1; i <= m; i++) {
cin >> u[i] >> v[i] >> w[i];//读入每条边
next[i] = first[u[i]];//建立邻接表
first[u[i]] = i;
}
que[tail] = 1;//1号顶点入队
tail++;
book[1] = 1;//标记
while (head < tail) {
int k = first[que[head]];//当前需要处理的队首顶点
while (k != -1) {//扫面次顶点的所有边
if (dis[v[k]]>dis[u[k]] + w[k]) {//判断是否松弛成功
dis[v[k]] = dis[u[k]] + w[k];//更新点1到v[k]的路程
if (book[v[k]] == 0) {//判断v[k]是否在队列中
que[tail] = v[k];//入队
tail++;
book[v[k]] = 1;//标记
}
}
k = next[k];
}
book[que[head]] = 0;//出队
head++;
}
for (int i = 1; i <= n; i++) {//输出1号顶点到其余个点的最短路径
cout << dis[i] << " ";
}
return 0;
}
输入
5 7
1 2 2
1 5 10
2 3 3
2 5 7
3 4 4
4 5 5
5 3 6
结果是
0 2 5 9 9 5 3 6