模板
#include <iostream>
#define MAX 9999999 // 表示边不存在,用INT32_MAX也可
using namespace std;
int main() {
int N, M; // 顶点数,边数
int C1, C2; // 起点,终点
int A[N][N]; // 记录路径长度
// 构造邻接矩阵
cin >> N >> M >> C1 >> C2;
fill_n(&A[0][0], N * N, MAX); // MAX表示不可达
for (int i = 0; i < N; i++) cin >> V[i];
int j, k; // 无向邻接图对称!
for (int i = 0; i < M; i++) {
cin >> j >> k >> A[j][k];
A[k][j] = A[j][k];
}
// 最短路径算法
int visit[N]; // 记录是否在点集中
int D[N]; // 记录C1到点i的最短路径
int min, v, w;
// 初始化(直通路径初始化)
for (int i = 0; i < N; i++) {
visit[i] = 0;
D[i] = A[C1][i]; // 记录直通的路径长
}
visit[C1] = 1; // C1加入已访问节点
D[C1] = 0; // C1到C1路径长为0
for (int i = 1; i < N; i++) {
// N-1轮
min = MAX;
v = -1;
for (w = 0; w < N; w++) {
if (!visit[w]) {
if (D[w] < min) {
v = w;
min = D[w];
}
}
}
if (v == -1) break;
visit[v] = 1;
for (w = 0; w < N; w++) {
//加入w节点,处理D[w]
if (!visit[w] && A[v][w] != MAX) {
// 访问未访问且有直通路径的节点w
if (min + A[v][w] < D[w]) {
// 如果当前记录的最短路径大于经过v的路径
D[w] = min + A[v][w]; // 更新D[w]
}
}
}
}
}
应用
参考《算法笔记》与《算法笔记-上机训练实战指南》,柳婼大神的博客
PAT1003
#include <iostream>
#define MAX 9999999
using namespace std;
int main() {
int N, M;
int C1, C2;
int V[N]; // 记录每个城市的救援队数量
int A[N][N]; // 记录路径长度
cin >> N >> M >> C1 >> C2;
fill_n(&A[0][0], N * N, MAX); // MAX表示不可达
for (int i = 0; i < N; i++) cin >> V[i];
int j, k; // 无向邻接图对称!
for (int i = 0; i < M; i++) {
cin >> j >> k >> A[j][k];
A[k][j] = A[j][k];
}
// 最短路径算法
int visit[N]; // 记录是否在点集中
int D[N]; // 记录C1到点i的最短路径
int W[N]; // 记录C1到点i救援队伍数量
int count[N]; // 记录C1到点i最短路径数
int min, v, w;
// 初始化(直通路径初始化)
for (int i = 0; i < N; i++) {
visit[i] = 0;
D[i] = A[C1][i]; // 记录直通的路径长
if (A[C1][i] != MAX) W[i] = V[C1] + V[i]; // 记录直通连接的路径权值
else W[i] = 0;
count[i] = 1; // C1到i肯定有一条路径
}
visit[C1] = 1; // C1加入已访问节点
D[C1] = 0; // C1到C1路径长为0
W[C1] = V[C1];
for (int i = 1; i < N; i++) {
min = MAX;
v = -1;
for (w = 0; w < N; w++) {
if (!visit[w]) {
if (D[w] < min) {
v = w;
min = D[w];
}
}
}
if (v == -1) break;
visit[v] = 1;
for (w = 0; w < N; w++) {
//加入w节点,处理D[w],W[w],count[w]
if (!visit[w] && A[v][w] != MAX) {
// 访问未访问且有直通路径的节点w
if (min + A[v][w] < D[w]) {
// 如果当前记录的最短路径大于经过v的路径
D[w] = min + A[v][w]; // 更新D[w]
count[w