leetcode787. K 站中转内最便宜的航班——优先队列优化的Dijkstra算法+剪枝

题目

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

题目分析

给定一个城市图,每个城市通过航班与其他城市相连。每个航班都有一个起点、终点和价格。你需要找到从起点城市 src 到终点城市 dst 的最便宜路径,但这条路径最多只能经过 k 个中转站。你需要返回这种路径的最低价格,如果不存在这样的路径,则返回 -1。

输入:

n:城市的数量

flights:航班的列表,每个航班用 [fromi, toi, pricei] 表示,表示从城市 fromi 到城市 toi 的航班价格为 pricei

src:起点城市

dst:终点城市

k:最多经过的中转站数

输出:

最便宜的价格,如果没有满足条件的路径,则输出 -1

思路分析

我看到这道题第一时间想的就是dijkstra算法,因为我也不会别的算法。

对于k的限制,我想到可以在优先队列中维护一个当前层级的变量,当到达的层级大于k时,就不再扩展了。

但是我没考虑到k的限制可能会导致最短路径无法达成,并且由于dijkstra算法的性质,其他路线也被直接丢弃了

于是我尝试不使用visited数组记录访问过的节点,将每个节点的后继节点都加入队列中,只有层级大于k时,才会跳过。此时算法退化成了变体的广度优先搜索算法,会搜索每一条在中转数在k内的路径。

但是,当数据量大了之后,显然这个算法会超时。

继续思考,发现dijkstra算法找到的是最优路径,但是其中转节点可能很多,而真正的路径只可能在中转节点比最优路径少的路径里,其他中转节点多于最优路径的路径完全可以剪枝,因为他们的费用不可能更低。

按照这个思路,只需要维护一个每个节点的最小中转数,任何多于最小中转数的路径都可以剪枝,因为对于每一个被剪枝的路径来说,在其之前都已经有至少一条路径价格比它低的同时中转数还要小于它

代码

python 复制代码
class Solution:
    def findCheapestPrice(self, n: int, flights: List[List[int]], src: int, dst: int, k: int) -> int:
        # 建立邻接表
        maps=[[]  for _ in range(n)]
        for edge in flights:
            maps[edge[0]].append(edge[1:])
        #最小堆模拟优先队列,(价格,节点编号,层级)
        pq=[(0,src,0)]
        #当前每个节点的中转数记录
        visit=[n+1]*n
        while pq:
            w,p,c=heappop(pq)
            #过滤超过层级k的节点,剪枝中转城市多余当前节点记录的点
            if c>=visit[p] or c>k+1:
                continue
            if  p == dst:
                return w
            # 直接等就可以,比它大的到不了这一步
            visit[p]=c
            # 将后继节点加入优先队列
            for point in maps[p]:
                heappush(pq,(w + point[1],point[0],c+1))

        return  -1
                

提交

一直交刷成绩QAQ


2024/8/8

相关推荐
qyzm41 分钟前
天梯赛练习(3月13日)
开发语言·数据结构·python·算法·贪心算法
逆境不可逃1 小时前
LeetCode 热题 100 之 64. 最小路径和 5. 最长回文子串 1143. 最长公共子序列 72. 编辑距离
算法·leetcode·动态规划
CoderCodingNo2 小时前
【GESP】C++五级练习题 luogu-P1182 数列分段 Section II
开发语言·c++·算法
放下华子我只抽RuiKe52 小时前
机器学习全景指南-直觉篇——基于距离的 K-近邻 (KNN) 算法
人工智能·gpt·算法·机器学习·语言模型·chatgpt·ai编程
kisshuan123962 小时前
[特殊字符]【深度学习】DA3METRIC-LARGE单目深度估计算法详解
人工智能·深度学习·算法
sali-tec2 小时前
C# 基于OpenCv的视觉工作流-章33-Blod分析
图像处理·人工智能·opencv·算法·计算机视觉
Eward-an2 小时前
LeetCode 239. 滑动窗口最大值(详细技术解析)
python·算法·leetcode
一叶落4383 小时前
LeetCode 50. Pow(x, n)(快速幂详解 | C语言实现)
c语言·算法·leetcode
皙然3 小时前
彻底吃透红黑树
数据结构·算法
t198751283 小时前
TOA定位算法MATLAB实现(二维三维场景)
开发语言·算法·matlab