112、K 站中转内最便宜的航班

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

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 k 站中转的最便宜的价格。 如果没有这样的路线,则输出 -1。

示例 1:
输入:
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1
输出: 200
解释:
城市航班图如下
在这里插入图片描述

在这里插入图片描述
代码:
这个数据结构想的也太好了,注意那个优先级队列的使用,非常好!!!

import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.stream.IntStream;
class Solution {
   public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
        PriorityQueue<int[]> pri = new PriorityQueue<>(
        		(a,b)->(a[0] - b[0])
        			
        		);
		Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
        for (int[] is : flights) {
			if(!map.containsKey(is[0])){
				map.put(is[0], new HashMap<>());
				
			}
			map.get(is[0]).put(is[1], is[2]);
		}
       
        pri.offer(new int[]{0,src,0});
		while (!pri.isEmpty()) {
			int []tem = pri.poll();
			int cost = tem[0];
			int temdest= tem[1];
			int k = tem[2];
			if(temdest == dst){
				return cost;
			}
            	
			if(k <= K){
				Map<Integer, Integer> maps = map.getOrDefault(temdest, new HashMap<>());
				for (Entry<Integer, Integer> i : maps.entrySet()) {
					pri.offer(new int[]{cost + i.getValue(),i.getKey(),k + 1});
				}
			}
			
		}
        return -1;
    }
}

动态规划算法,速度很快

import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
class Solution {
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
  //		 基于动态规划的算法
		 int dp[][] = new int[n][K + 2];
		 for (int i = 0; i < dp.length; i++) {
			Arrays.fill(dp[i], Integer.MAX_VALUE);
		}
		 
		 for (int i = 0; i <= K + 1; i++) {
			dp[src][i] = 0;
		}
		 
		 for (int i = 1; i <= K + 1; i++) {
			for (int[] is : flights) {
				if(dp[is[0]][i-1] != Integer.MAX_VALUE){
					dp[is[1]][i] = Math.min(dp[is[1]][i], dp[is[0]][i-1] + is[2]);
				}
			}
		}
		return dp[dst][K+1] == Integer.MAX_VALUE ? -1 :dp[dst][K+1];
		 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值