题目地址:

https://www.lintcode.com/problem/cheapest-flights-within-k-stops/description

给定一个非负权有向图,再给定一个源点sss,一个目标点ddd,和一个整数KKK,问从sss到ddd中转站个数(其实就是路径去掉起点和终点后剩余的点数)不超过KKK的最短路径长度。若不存在则返回−1-1−1。

法1:Bellman-Ford算法。一共更新K+1K+1K+1轮,每轮都对每条边进行松弛操作。具体代码实现方面要注意,在进行第iii轮松弛的时候,需要用第i−1i-1i−1轮松弛的结果,而不能实时更新,否则会得到错误答案。代码如下:

import java.util.*;public class Solution {/*** @param n:       a integer* @param flights: a 2D array* @param src:     a integer* @param dst:     a integer* @param K:       a integer* @return: return a integer*/public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {// write your code hereif (flights == null || flights.length == 0 || flights[0].length == 0) {return 0;}// 用邻接表建图。key是边的出发点,value的下标0存边的到达点,下标1存边权Map<Integer, List<int[]>> graph = buildGraph(flights);// dis存编号为i的点到源点的最短路距离,先初始化为正无穷。源点自己初始化为0int[] dis = new int[n];Arrays.fill(dis, Integer.MAX_VALUE);dis[src] = 0;// pass表示更新的轮数。当一遍循环结束时,就找到了边的数量不超过pass的最短路的长度;// K是中转站个数,也就等于边数减1for (int pass = 1; pass <= K + 1; pass++) {// 这里为了防止在某次相同循环里出现用更新过的dis再去更新别的dis的错误情况,需要对前一轮pass的dis做备份int[] backup = Arrays.copyOf(dis, dis.length);// 枚举图的每个点for (int i = 0; i < n; i++) {// 更新其出边if (graph.containsKey(i)) {for (int[] next : graph.get(i)) {int nextPoint = next[0], disFromI = next[1];// 注意,当某个点的dis是正无穷的时候,其出边是不能更新的if (backup[i] != Integer.MAX_VALUE) {dis[nextPoint] = Math.min(dis[nextPoint], backup[i] + disFromI);}}}}}// 如果dis是正无穷说明到不了,返回-1;否则返回那个距离return dis[dst] == Integer.MAX_VALUE ? -1 : dis[dst];}private Map<Integer, List<int[]>> buildGraph(int[][] g) {Map<Integer, List<int[]>> graph = new HashMap<>();for (int[] tuple : g) {graph.putIfAbsent(tuple[0], new ArrayList<>());graph.get(tuple[0]).add(new int[]{tuple[1], tuple[2]});}return graph;}
}

时间复杂度O(KE)O(KE)O(KE),空间O(V+E)O(V+E)O(V+E)。

法2:SPFA。在Bellman-Ford算法基础上进行优化,用一个队列,每次只有当松弛操作会产生更优路线的时候才会将被松弛的边的那个到达点加入队列中,进行下面的优化。同时,开一个数组记录源点到其余顶点的最短路的长度,在每次松弛的时候,都更新之;而一旦发现某个点更新完后其最短路长度已经达到了K+1K+1K+1了,也不能将其加入队列,因为用其更新别的点的最短路只会产生路径长度更长的最短路,这是不符合要求的。代码如下:

import java.util.*;public class Solution2 {/*** @param n:       a integer* @param flights: a 2D array* @param src:     a integer* @param dst:     a integer* @param K:       a integer* @return: return a integer*/public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {// write your code hereif (flights == null || flights.length == 0 || flights[0].length == 0) {return 0;}Map<Integer, List<int[]>> graph = buildGraph(flights);int[] dis = new int[n];Arrays.fill(dis, Integer.MAX_VALUE);dis[src] = 0;// 记录当前算出的到该顶点的最短路的边的数量int[] count = new int[n];// 记录当前顶点是否已经存在于队列boolean[] state = new boolean[n];Queue<Integer> queue = new LinkedList<>();queue.offer(src);while (!queue.isEmpty()) {int cur = queue.poll();state[cur] = false;if (graph.containsKey(cur)) {for (int[] next : graph.get(cur)) {int nextPoint = next[0], disFromCur = next[1];if (dis[nextPoint] > dis[cur] + disFromCur) {dis[nextPoint] = dis[cur] + disFromCur;count[nextPoint] = count[cur] + 1;// 判断一下nextPoint的最短路的边的数量是小于等于K的,如果不满足也不能加入队列if (!state[nextPoint] && count[nextPoint] <= K) {queue.offer(nextPoint);state[nextPoint] = true;}}}}}return dis[dst] == Integer.MAX_VALUE ? -1 : dis[dst];}private Map<Integer, List<int[]>> buildGraph(int[][] g) {Map<Integer, List<int[]>> graph = new HashMap<>();for (int[] tuple : g) {graph.putIfAbsent(tuple[0], new ArrayList<>());graph.get(tuple[0]).add(new int[]{tuple[1], tuple[2]});}return graph;}
}

时间复杂度O(KE)O(KE)O(KE),空间O(V+E)O(V+E)O(V+E),虽然最差情况一样,但在大多数情况下还是要比Bellman-Ford算法快很多。

【Lintcode】1029. Cheapest Flights Within K Stops相关推荐

  1. [lintcode] 1029. Cheapest Flights Within K stops [Medium]

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

  2. Cheapest Flights Within K Stops

    [leetcode]Cheapest Flights Within K Stops 链接:https://leetcode.com/problems/cheapest-flights-within-k ...

  3. LeetCode——787. K 站中转内最便宜的航班(Cheapest Flights Within K Stops)[中等]——分析及代码(Java)

    LeetCode--787. K 站中转内最便宜的航班[Cheapest Flights Within K Stops][中等]--分析及代码[Java] 一.题目 二.分析及代码 1. 动态规划 ( ...

  4. leetcode 787. Cheapest Flights Within K Stops | 787. K 站中转内最便宜的航班(BFS)

    题目 https://leetcode.com/problems/cheapest-flights-within-k-stops/ 题解 这题挺坑的实际上.DFS 超时了,因为涉及到步数限制 k,所以 ...

  5. LeetCode 787. Cheapest Flights Within K Stops

    题解 这题看似最短路径,但是暗藏变化. 首先想到dfs,搜索到所有由始至终的可行路径,记录最小cost即可. 但是这题编程实现有很多小花招,怎么剪枝,一个是k(步进的次数), 二是cost,都可以用来 ...

  6. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  7. 【LintCode】算法题 1443. 最长AB子串

    描述 给你一个只由字母'A'和'B'组成的字符串s,找一个最长的子串,要求这个子串里面'A'和'B'的数目相等,输出该子串的长度. 这个子串可以为空. s的长度n满足 2<=n<=1000 ...

  8. 【Lintcode】1375. Substring With At Least K Distinct Characters

    题目地址: https://www.lintcode.com/problem/substring-with-at-least-k-distinct-characters/description 给定一 ...

  9. 【lintcode】树形数据结构之Maxtree, Tree iterator, remove bst node, 优先队列之动态中位数Median, 矩阵dfs之word search II,最大连

    解析 max ksubarray sum:  最大和 of 连续子序列 =>   最大和 of  k份连续子序列 属于dp,30行代码搞定,注意一些边界. substr diff:  无queu ...

最新文章

  1. 《预训练周刊》第19期:歧义短语的类量子语境性研究、自然语言处理中prompt方法的系统综述...
  2. sqlserver 时间格式函数详细
  3. 基于 Spring Cloud 的服务治理实践
  4. 医学论文论题该如何下手
  5. DenyHosts教程:防暴力破解SSH密码
  6. 如何优化JavaScript脚本的性能
  7. php保存rar,php 解压rar文件
  8. c#hello world_C#| 打印消息/文本(用于打印Hello world的程序)
  9. 有了这个数据强一致“利器”,DBA们轻松修复数据对加班“say no”
  10. 在ubuntu下配置C和C++的编译环境
  11. Machine Learning——Homework4
  12. ssm框架整合以及登录案例
  13. 文件同步工具 GoodSync Enterprise 破解
  14. OMNeT 例程 Tictoc12 学习笔记
  15. 数据结构/排序/选择排序/简单选择排序
  16. 图片拉伸和保持长宽比的问题
  17. 青少年初学哪门语言类编程比较好?
  18. c语言单项选择题及答案,2011年计算机二级C语言单项选择题及答案解析精选3
  19. java自动发图文微博_使用node搭建自动发图文微博机器人的方法
  20. < 谈谈对 SPA(单页面应用)的理解 >

热门文章

  1. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java通识教育教学系统ekzep
  2. 全球及中国复印机市场规模预测及投资价值预测报告2022-2028年
  3. dedescms 标签
  4. 2021最新Android框架体系架构面试题-如何成为一个更好的Android开发者?送大厂面经一份!
  5. 谈生于1987-1991的这代人
  6. 中国量子计算机无花果,2019年中国无花果市场供需现状及进出口情况分析 [图]...
  7. 正确安装 torch_geometric库
  8. appium连接模拟器
  9. 【pytorch 优化器】ReduceLROnPlateau详解
  10. Tableau之数据可视化大屏/智慧大屏(成都大熊猫繁育研究基地,模拟旅游相关数据)@灵魂走风的江湖