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

相关推荐
weixin_429630268 分钟前
第6章 支持向量机
算法·机器学习·支持向量机
SweetCode8 分钟前
C++ 实现大数加法
开发语言·c++·算法
王哈哈^_^9 分钟前
【数据集】【YOLO】【目标检测】共享单车数据集,共享单车识别数据集 3596 张,YOLO自行车识别算法实战训推教程。
人工智能·算法·yolo·目标检测·计算机视觉·视觉检测·毕业设计
CodeWizard~1 小时前
AtCoder Beginner Contest 430赛后补题
c++·算法·图论
大大dxy大大1 小时前
机器学习-KNN算法示例
人工智能·算法·机器学习
关于不上作者榜就原神启动那件事2 小时前
模拟算法乒乓球
开发语言·c++·算法
Bug退退退1232 小时前
ArrayList 与 LinkedList 的区别
java·数据结构·算法
88号技师3 小时前
2025年7月一区SCI优化算法-Logistic-Gauss Circle optimizer-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
一个不知名程序员www4 小时前
算法学习入门---二分查找(C++)
c++·算法
2301_807997384 小时前
代码随想录-day26
数据结构·c++·算法·leetcode