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

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems
特别鸣谢:来自夸夸群的 醉笑陪公看落花@知乎王不懂不懂@知乎
感谢醉笑陪公看落花@知乎 倾囊相授,感谢小伙伴们督促学习,一起进步

有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi。

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1。

示例 1:

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

在这里插入图片描述

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cheapest-flights-within-k-stops

DFS - 超时

import functools


class Solution:
    def findCheapestPrice(self, n: int, flights, src: int, dst: int, k: int) -> int:
        # 转图
        graph = {}
        for u,v,e in flights:
            if u not in graph:graph[u]={}
            graph[u][v] = e
        @functools.lru_cache()
        def dfs(node,via=-1):
            if via == k:return float('inf')
            if node == dst:return 0
            if node not in graph:return float('inf')
            return min([graph[node][tpnode]+(dfs(tpnode,via+1) if tpnode!=dst else 0) for tpnode in graph[node]])
        ans = dfs(src)
        return -1 if ans ==float('inf') else ans

dp - src到中转到dst的最小花费- 通过

class Solution:
    def findCheapestPrice(self, n: int, flights, src: int, dst: int, k: int) -> int:
        graph = {}
        for u,v,e in flights:
            if v not in graph:graph[v]={}
            graph[v][u] = e
        # f[t][i] 表示通过恰好 t 次航班,从出发城市 src 到达城市i需要的最小花费
        # f[t][i] = f[t-1][j]+cost(j->i)
        f = [[float('inf')]*n for _ in range(k+1)]
        f[0] = [graph[i][src] if i in graph and src in graph[i] else float('inf') for i in range(n)]
        for t in range(1,k+1):
            for i in graph:
                f[t][i] = min([graph[i][j]+(f[t-1][j] if j!=src else 0) for j in graph[i]],default=float('inf'))
        ans = f[k][dst]
        return -1 if ans == float('inf') else ans

效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值