用vs2017调试了一下,主要的问题就是初始化不完全,尤其是没有对vis数组初始化。在调试的过程中,把数据的输入改成文件形式了,不想弄成鼠标手^_^
#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
using namespace std;
const int SIZE = 500;
int dis[SIZE]; // 出发点到各点的最短估计距离
int path[SIZE]; // 路径上到达该点的上一顶点
int a[SIZE][SIZE]; // a[i][j]表示i到j路径的权值
// n为顶点数,s为出发点
// 各顶点编号从1始起
void spfa(int n, int s)
{
const int INF = 999999; // 初始最短路径估计值
int vis[SIZE]; // 该点是否被访问过
int q[SIZE]; // 用于实现spfa的队列
for (int i = 1; i <= n; i++)
{
path[i] = -1;
dis[i] = INF;
vis[i] = 0;
}
dis[s] = 0; vis[s] = 1; q[1] = s;
int v, head = 0, tail = 1;
while (head < tail)
{
head++;
v = q[head];
vis[v] = 0; // 出队
for (int i = 1; i <= n; i++)
{
if (a[v][i] > 0 && dis[i] > dis[v] + a[v][i])
{
dis[i] = dis[v] + a[v][i];
path[i] = v;
if (vis[i] == 0)
{
tail++;
q[tail] = i;
vis[i] = 1; // 入队
}
}
}
}
}
// k为终点
void printpath(int k)
{
if (path[k] != -1)
printpath(path[k]);
cout << " -> " << k;
}
int main()
{
#define W setw(4)
ifstream in("in.txt");
if (!in.is_open())
{
cout << "未打开in.txt,请检查文件是否在当前目录下";
return 0;
}
int n, s; // 顶点数,出发点
in >> n >> s;
cout << "输入顶点数、出发点:" << n << " " << s << endl;
cout << "输入各条路径的起点、终点、权值:" << endl;
int i = 1;
while (in.peek() != EOF) // in.eof()会多读一行
{
int x, y, w;
in >> x >> y >> w;
a[x][y] = w;
//a[y][x] = w;
cout << " 第(" << W << i++ << ")条边:";
cout << W << x << W << y << W << w << endl;
}
cout << endl;
spfa(n, s);
cout << "从 " << s << " 到 " << n << "的最短路径: " << dis[n] << endl;
printpath(n);
return 0;
}
in文件内容:
11 1
1 2 5
1 3 3
2 4 1
2 5 3
2 6 6
3 5 8
3 6 7
3 7 6
4 8 6
4 9 8
5 8 3
5 9 5
6 9 3
6 10 3
7 9 8
7 10 4
8 11 3
9 11 2
10 11 2
百科里面有个经典的c++ spfa程序,那个用了一点stl的知识,数组也从0始计数,你可以参考一下: