JAVA程序设计:K 站中转内最便宜的航班(LeetCode:787)

有 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
解释: 
城市航班图如下


从城市 0 到城市 2 在 1 站中转以内的最便宜价格是 200,如图中红色所示。
示例 2:

输入: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 0
输出: 500
解释: 
城市航班图如下


从城市 0 到城市 2 在 0 站中转以内的最便宜价格是 500,如图中蓝色所示。

提示:

n 范围是 [1, 100],城市标签从 0 到 n - 1.
航班数量范围是 [0, n * (n - 1) / 2].
每个航班的格式 (src, dst, price).
每个航班的价格范围是 [1, 10000].
k 范围是 [0, n - 1].
航班没有重复,且不存在环路

思路:Dijkstra最短路变形题,多加一维用来存储中间经过了多少中转站。

class Solution {
	
	class node{
		int v,val;
		public node(int v,int val) {
			this.v=v;
			this.val=val;
		}
	}
	
	class node1{
		int id,num,val;
		public node1(int id,int num,int val) {
			this.id=id;
			this.num=num;
			this.val=val;
		}
	}
	
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
    	
    	int ans=Integer.MAX_VALUE;
    	int[][] dis=new int[n][K+1];
    	Queue<node1> q=new LinkedList<>();
    	Map<Integer,List<node>> road=new HashMap<>();
    	
    	for(int i=0;i<flights.length;i++) {
    		if(!road.containsKey(flights[i][0]))
    			road.put(flights[i][0], new ArrayList<>());
    		road.get(flights[i][0]).add(new node(flights[i][1],flights[i][2]));
    	}
    	
    	for(int i=0;i<n;i++)
    		for(int j=0;j<=K;j++)
    			dis[i][j]=Integer.MAX_VALUE-20000;
    	
    	q.add(new node1(src,0,0));
    	dis[src][0]=0;
    	
    	while(!q.isEmpty()) {
    		node1 now=q.poll();
    		//System.out.println(now.id);
    		if(now.id==dst || !road.containsKey(now.id))
    			continue;
    		//System.out.println(now.val);
    		for(int i=0;i<road.get(now.id).size();i++) {
    			int index=road.get(now.id).get(i).v;
    			int weight=road.get(now.id).get(i).val;
    			int num=(index==dst?now.num:now.num+1);
    			if(num>K) continue;
    			if(dis[index][num]>dis[now.id][now.num]+weight) {
    				dis[index][num]=dis[now.id][now.num]+weight;
    				q.add(new node1(index,num,dis[index][num]));
    			}
    		}
    	}
    	
    	for(int i=0;i<=K;i++)
    		ans=Math.min(ans, dis[dst][i]);
    	return ans==Integer.MAX_VALUE-20000?-1:ans;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值