题解: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

【解题思路】

image

【算法标签】

《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
posted @ 2026-02-21 20:13  团爸讲算法  阅读(0)  评论(0)    收藏  举报