LeetCode - 787. K 站中转内最便宜的航班

787. K 站中转内最便宜的航班

有 n 个城市通过 m 个航班连接。每个航班都从城市 u 开始,以价格 w 抵达 v。

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 k 站中转的最便宜的价格。 如果没有这样的路线,则输出 -1。
在这里插入图片描述
在这里插入图片描述
解题思路:本题的场景可以转化为在给定的最大深度下找加权最短路的问题。那么图的遍历有两种方式,这里对应的给出两种解法。

  1. 深度优先搜索
class Solution {
public:
    void helper(unordered_map<int, vector<vector<int>>>& m, unordered_set<int>& visited, int cur, int K, int dst, int out, int &res) {
        if (cur == dst) {res = out; return;}
        if (K < 0) return;
        for (auto a : m[cur]) {
            if (visited.count(a[0]) == 1 || out + a[1] > res) continue;
            visited.insert(a[0]);
            helper(m, visited, a[0], K - 1, dst, out + a[1], res);
            visited.erase(a[0]);
            
        }
    }
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        int res = INT_MAX;
        unordered_map<int, vector<vector<int>>> m;
        unordered_set<int> visited;
        for (auto flight : flights) {
            m[flight[0]].push_back({flight[1], flight[2]});
        }
        helper(m, visited, src, K, dst, 0, res);
        return res == INT_MAX ? -1 : res;
    }
};
  1. 广度优先遍历
class Solution {
public:
    
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        int res = INT_MAX;
        unordered_map<int, vector<vector<int>>> m;
        unordered_set<int> visited;
        for (auto flight : flights) {
            m[flight[0]].push_back({flight[1], flight[2]});
        }
        int cnt = 0;
        queue<vector<int>> q{{{src, 0}}};
        while (!q.empty()) {
            for (int i = q.size(); i > 0; --i) {
                auto t = q.front(); q.pop();
                if (t[0] == dst) {res = min(res, t[1]);}
                for (auto a : m[t[0]]) {
                    if (t[1] + a[1] > res) continue;
                    q.push({a[0], t[1] + a[1]});
                }
            }
            if (cnt++ > K) break;
        }
        return res == INT_MAX ? -1 : res;
    }
};

参考资料

[LeetCode] Cheapest Flights Within K Stops K次转机内的最便宜的航班

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值