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

相关推荐
CoderYanger4 分钟前
贪心算法:5.最长递增子序列
java·算法·leetcode·贪心算法·1024程序员节
慕容青峰6 分钟前
【牛客周赛 107】E 题【小苯的刷怪笼】题解
c++·算法·sublime text
算法熔炉11 分钟前
深度学习面试八股文(2)——训练
人工智能·深度学习·算法
EXtreme3520 分钟前
【数据结构】打破线性思维:树形结构与堆在C语言中的完美实现方案
c语言·数据结构·算法··heap·完全二叉树·topk
cici1587421 分钟前
含风电场的十机24时系统机组出力优化算法
人工智能·算法·机器学习
WolfGang00732126 分钟前
代码随想录算法训练营Day45 | 101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿
算法·深度优先
2301_7644413327 分钟前
PMC政策文本量化评估
python·算法·信息可视化
代码游侠32 分钟前
应用——Linux进程编程实例分析
linux·运维·网络·笔记·学习·算法
DuHz35 分钟前
《Around the Corner mmWave Imaging in Practical Environments》论文精读
论文阅读·算法·信息与通信·毫米波雷达
CoderYanger39 分钟前
D.二分查找-基础-2529. 正整数和负整数的最大计数
java·开发语言·数据结构·算法·leetcode·职场和发展