一、算法介绍
SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。
二、示例演示
三、程序代码分析
就是把dijkstra算法中对起始点到其他点的距离的最小值的代码换成了用一个队列去进行判断。其他的同dijkstra算法相同。
四、程序编写
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<queue>
#define INTMAX 65535
//存储图信息:6个顶点8条边
int a[6][6] =
{ { INTMAX, INTMAX, 10, INTMAX, 30, 100 },
{ INTMAX, INTMAX, 5, INTMAX, INTMAX, INTMAX },
{ INTMAX, INTMAX, INTMAX, 50, INTMAX, INTMAX },
{ INTMAX, INTMAX, INTMAX, INTMAX, INTMAX, 10 },
{ INTMAX, INTMAX, INTMAX, 20, INTMAX, 60 },
{ INTMAX, INTMAX, INTMAX, INTMAX, INTMAX, INTMAX }
};
//存储起始点到各个顶点的最短路径长度信息
queue <int> q;
int b[6] = { INTMAX, INTMAX, INTMAX, INTMAX, INTMAX, INTMAX };
//存储数组b中最小值是否访问的标志位,访问后置为0
int c[6] = { INTMAX, INTMAX, INTMAX, INTMAX, INTMAX, INTMAX };
//存储起始点到各个顶点的最短路径过程信息
string d[6] = { "", "", "", "", "", "" };
//spfa算法
void spfa(){
int temp = 0; //数组b中最小的值的下标
q.push(0);
b[0] = 0;
d[0] = "1->" + to_string(1);
int count = 1;
c[0] = 0;
while (count<6){
//找出数组b中最小的值
if (!q.empty()){
temp = q.front();
q.pop();
}
//如果b中的值不是原始值,说明路径更新过
if (b[temp] == a[0][temp]){
d[temp] = "1->" + to_string(temp + 1);
}
//每得到一次最小值肯定能确定一个最小路径,则while循环就减一次
count++;
c[temp] = 0;
//最小值与该点到其他顶点的值的和是否小于初始点到其他顶点的值
for (int i = 0; i < 6; i++){
if (b[temp] + a[temp][i] < b[i]){
b[i] = b[temp] + a[temp][i];
d[i] = d[temp] + "->" + to_string(i + 1);
if (c[i]>0){
q.push(i);
}
}
}
}
}
void main(){
spfa();
cout << "最短路径长度:" << endl;
for (int i = 0; i < 6; i++){
cout << b[i] << " ";
}
cout << endl << "最短路径:" << endl;
for (int i = 0; i < 6; i++){
if (b[i] == INTMAX) d[i] = "无";
cout << d[i] << " ";
}
system("pause");
}