题解:AcWing 853 有边数限制的最短路
【题目来源】
AcWing:853. 有边数限制的最短路 - AcWing题库
【题目描述】
给定一个\(n\)个点\(m\)条边的有向图,图中可能存在重边和自环,边权可能为负数。请你求出从\(1\)号点到\(n\)号点的最多经过\(k\)条边的最短距离,如果无法从\(1\)号号点走到\(n\)号点,输出impossible。 注意:图中可能存在负权回路
【输入】
第一行包含三个整数 \(n,m,k\)。接下来\(m\)行,每行包含三个整数\(x,y,z\),表示存在一条从点\(x\) 到点\(y\)的有向边,边长为\(z\)。点的编号为\(1\sim n\)。
【输出】
输出一个整数,表示从\(1\)号点到\(n\)号点的最多经过\(k\)条边的最短距离。如果不存在满足条件的路径,则输出 impossible。
【输入样例】
3 3 1
1 2 1
2 3 1
1 3 3
【输出样例】
3
【解题思路】

【算法标签】
《AcWing 853 有边数限制的最短路》 #最短路# #Bellman-Ford#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
// 定义常量,N为最大节点数,M为最大边数,INF为无穷大
const int N = 510, M = 10010, INF = 1e9;
// 定义距离数组dist和备份数组backup
int dist[N], backup[N];
// 定义边结构体,包含起点a,终点b,权重w
struct edge {
int a, b, w;
};
// 定义边数组edges
edge edges[M];
// 定义节点数n,边数m,最多迭代次数k
int n, m, k;
// Bellman-Ford算法实现
int bellman() {
// 初始化距离数组dist为无穷大,起点距离设为0
fill(dist, dist + N, INF);
dist[1] = 0;
// 进行k次迭代
for (int i = 0; i < k; i++) {
// 备份当前的距离数组
memcpy(backup, dist, sizeof(dist));
// 遍历所有边,更新距离数组
for (int j = 0; j < m; j++) {
int a = edges[j].a, b = edges[j].b, w = edges[j].w;
dist[b] = min(dist[b], backup[a] + w);
}
}
// 返回终点n的距离,如果距离仍为无穷大则返回-1
return dist[n];
}
int main() {
// 输入节点数n,边数m,最多迭代次数k
cin >> n >> m >> k;
// 输入每条边的起点a,终点b,权重w
for (int i = 0; i < m; i++) {
int a, b, w;
cin >> a >> b >> w;
edges[i] = {a, b, w};
}
// 调用Bellman-Ford算法计算最短路径
int ans = bellman();
// 如果结果大于等于INF/2,说明不存在从起点到终点的路径,输出"impossible"
if (ans >= INF / 2) cout << "impossible";
else cout << dist[n] << endl;
return 0;
}
【运行结果】
3 3 1
1 2 1
2 3 1
1 3 3
3
浙公网安备 33010602011771号