[Leetcode] 787. Cheapest Flights Within K Stops 解题报告

这道题是图遍历问题,要求找到从起点到终点不超过K站的最便宜航班。通过修改Bellman-Ford算法,循环K+1次更新最短路径。算法思路包括初始化所有顶点距离为INT_MAX,源点距离为0,然后进行K+1次迭代,检查每条边是否能减少路径成本。执行完后,若终点距离不是INT_MAX,则存在满足条件的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

There are n cities connected by m flights. Each fight starts from city and arrives at v with a price w.

Now given all the cities and fights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1.

Example 1:
Input: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1
Output: 200
Explanation: 
The graph looks like this:


The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as marked red in the picture.
Example 2:
Input: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 0
Output: 500
Explanation: 
The graph looks like this:


The cheapest price from city 0 to city 2 with at most 0 stop costs 500, as marked blue in the picture.

Note:

  • The number of nodes n will be in range [1, 100], with nodes labeled from 0 to n - 1.
  • The size of flights will be in range [0, n * (n - 1) / 2].
  • The format of each flight will be (src, dst, price).
  • The price of each flight will be in the range [1, 10000].
  • k is in the range of [0, n - 1].
  • There will not be any duplicated flights or self cycles.

思路

一道图遍历的题目。由于要求最短路径中间经过的顶点数目不能超过K个,所以整个最短路径的跳转次数不能超过K + 1。因此我们可以通过修改Bellman-Ford算法来实现:循环K+1次,每次更新一下每条边导致的权重减少。算法的描述如下:

1)创建源顶点src到图中所有顶点的最短距离的集合,并初始化为INT_MAX,但是将源顶点的最短路径距离置为0;

2)计算最短路径,执行K + 1次遍历:对于图中的每条边,如果起点u的距离d加上边的权值w小于终点v的距离d,则更新终点v的距离值d。

这样当执行完K+1次遍历之后,如果顶点dst的距离不为INT_MAX,就说明从src到dst存在长度不超过K+1的最短路径。Bellman-Ford算法其实采用了动态规划的思想,是最简单优雅但是又最有效的算法之一。

代码

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<int> dp(n, INT_MAX);
        dp[src] = 0;
        for(int z = 0; z <= K; ++z){
            vector<int> temp_dp(dp);
            for(auto e: flights) {
                if (dp[e[0]] < INT_MAX) {
                    temp_dp[e[1]] = min(temp_dp[e[1]], dp[e[0]] + e[2]);
                }
            } 
            dp = temp_dp;
        }
        return dp[dst] == INT_MAX ? -1 : dp[dst];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值