力扣:K 站中转内最便宜的航班

题目描述


n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是 找到出一条最多经过 k 站中转的路线,使得从 src 到 dst 的 价格最便宜 , 并返回该价格。 如果不存在这样的路线,则输出 -1。
力扣:787. K 站中转内最便宜的航班

输入:
n = 3, edges = [[0 , 1 , 100] , [1 , 2 , 100] , [0 , 2 , 500]]
src = 0 , dst = 2 , k = 1
输出: 200

题目分析: 既然是求最短路径,BFS 也是可以的,不过,考虑到用例非常大的情况,我们需要认真的思考剪枝的方案,本题我们申请一个 ans[] 数组记录从 src 到 i 的最小价格,下次再遍历到 i 时,如果价格比记录的值小才计算,否则直接丢弃。

class Solution {
    private int INF = 1000007;
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
        List<int[]>[] g = new List[n];
        // 将 flights 转换为邻接表
        for(int i = 0 ; i < n ; i ++){
            g[i] = new ArrayList<>();
        }
        for(int[] flight : flights){
            g[flight[0]].add(new int[]{flight[1] , flight[2]});
        }

        // 表示 src 到 i 最小价格
        int[] ans = new int[n];
        Arrays.fill(ans , INF);
        Queue<int[]> que = new LinkedList<>();
        que.offer(new int[]{src , 0});
        // 退出条件加上 k 的限制
        while(!que.isEmpty() && k >= 0){
            int size = que.size();
            for(int i = 0 ; i < size ; i ++){
                int[] temp = que.poll();
                for(int[] path : g[temp[0]]){
                    int distance = temp[1] + path[1];
                    // 剪枝1: 小于 i 之前记录的最小值 , 且小于 dst 之前记录的最小值
                    if(distance < ans[path[0]] && distance < ans[dst]){
                        ans[path[0]] = distance;
                        // 剪枝2: 到 dst 了就不用继续往下了
                        if(path[0] != dst){
                            que.offer(new int[]{path[0] , distance});
                        }
                    }
                }
            }
            k --;
        }
        return ans[dst] >= INF ? -1 : ans[dst];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值