787. K 站中转内最便宜的航班(加权有向图的最短路径)

题目:787. K 站中转内最便宜的航班

两种方法:

在这里插入图片描述
在这里插入图片描述

方法一:

思路: 加权图的最短路径
1. 首先将航线转化为字典形式存储。(当前城市–下一城市–费用)
2. 建一个双向队列,元素为元组形式。(当前城市,src到当前城市的费用,中转次数)
3. 记录src到目的地dst的最小费用cheapest=1e6。(先设置为一个很大的数,这样在最后若cheapest=1e6,则说明没有从src到dst的路径,此时,返回-1)
4. 然后处理队列:
4.1 终止条件:K>2;
4.2 若遇到目的地,更新cheapest;
4.3 否则,若到某一中转站时,费用已经超过到底目的地的费用时,则果断放弃这一路线;只记录费用在cheapest内的中转站信息(中转站,src到中转站的费用,中转次数);
4.4 找出记录d中抵达终点站dst的记录。
注意点:d中元素为中转站时,会有好多条记录。如(r, 1500,2),(r,2000,2)。
class Solution(object):
    def findCheapestPrice(self, n, flights, src, dst, K):
        """
        :type n: int
        :type flights: List[List[int]]
        :type src: int
        :type dst: int
        :type K: int
        :rtype: int
        """
        dic = collections.defaultdict(dict)
        for u, v, w in flights:
            dic[u][v] = w
        d = collections.deque([(src, 0, 0)]) # 出发城市、src到出发城市需要的价格、中转次数
        cheapest = 1e6
        while d:
            if d[0][2] > K:
                break
            u, w, n = d.popleft()
            if u == dst:
                cheapest = min(cheapest, w)
            else:
                for v in dic[u]:
                    if dic[u][v] + w < cheapest: # 及时停止
                        d.append((v, dic[u][v]+w, n+1))
        while d:
            u, w, n = d.popleft()
            if u == dst:
                cheapest = min(cheapest, w)
        return cheapest if cheapest != 1e6 else -1
        

方法二:动态规划

思路: 采用动态规划来做,维护一个二维数组dp[k][i],其中dp[k][i]意思是中转k次到目的地为i的费用是多少。
1. 初始化dp[0][src]=0;
2. 则递推公式为:中转k次到达目的地i的费用等于=min(其他航线中转k次到达目的地,此次航线中转k-1次到达目的地i的前一站的费用+目的地i的前一站飞到目的地的费用)。
        dp = [[1e9 for i in range(n)] for j in range(K+2)]
        dp[0][src] = 0
        for i in range(1,K+2):
            for item in flights:
                dp[i][item[1]] = min(dp[i][item[1]], dp[i-1][item[0]] + item[2])
class Solution(object):
    def findCheapestPrice(self, n, flights, src, dst, K):
        """
        :type n: int
        :type flights: List[List[int]]
        :type src: int
        :type dst: int
        :type K: int
        :rtype: int
        """
        dp = [[1e9 for i in range(n)] for j in range(K+2)]
        dp[0][src] = 0
        for i in range(1,K+2):
            for item in flights:
                dp[i][item[1]] = min(dp[i][item[1]], dp[i-1][item[0]] + item[2])
        cheapest = 1e9
        for k in range(K+2):
            cheapest = min(cheapest, dp[k][dst])
        if cheapest >= 1e9:
            return -1
        else:
            return cheapest

猜你喜欢

转载自blog.csdn.net/zyy848877920/article/details/88886414
今日推荐