There are n cities connected by m flights. Each fight starts from city u and arrives at v with a price w.Now given all the cities and fights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1.node
Example 1:
Input: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 1
Output: 200 Explanation: The graph looks like this:
https://s3-lc-upload.s3.amazo...
The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as marked red in the picture.pythonNote:數組
The number of nodes n will be in range [1, 100], with nodes labeled from 0 to n - 1.
The size of flights will be in range [0, n * (n - 1) / 2].
The format of each flight will be (src, dst, price).
The price of each flight will be in the range [1, 10000]k
is in the range of [0, n - 1]. There will not be any duplicated flights or self cycles.app
給定一個數組,其中每一個元素表明着從[出發城市,目的城市,飛機票價],如今再給定任意一對不必定有直飛航線的出發城市和目的城市,和最大容許的中轉次數K,求具備最便宜總價的航線組合。this
想知道從A到B最便宜的機票組合,只要將全部從A到B在K箇中轉以內的全部路徑組合都遍歷一遍,就能找到最低的價格。然而本題的輸入是城市之間的航線,因此咱們還要先根據這些航線構建一個航線圖。因爲題中說明了不會產生環路,也不會有重複的航線,因此在遍歷圖時不須要檢測環路。code
這裏須要剪枝減小搜索分叉才能經過OJ,剪枝的要點包括:orm
class GraphNode: def __init__(self, name): self.name = name self.dsts = [] def addFlight(self, dst, price): self.dsts.append((dst, price)) class Solution: 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 """ flightsMap = self.constructGraph(flights) self.globalMin = float('inf') self.findFlight(flightsMap, flightsMap.get(src), 0, dst, 0, K, set()) return -1 if self.globalMin == float('inf') else self.globalMin def findFlight(self, flightsMap, node, totalPrice, finalDst, stops, stopLimit, visited): if node is None or stops > stopLimit: return if self.globalMin < totalPrice: return for dst in node.dsts: dstName, dstPrice = dst nextTotalPrice = dstPrice + totalPrice if dstName == finalDst: # 若是找到目的地,則計算當前的距離並和最小值比較 self.globalMin = min(self.globalMin, nextTotalPrice) elif flightsMap.get(dstName) is not None and self.globalMin > nextTotalPrice and dstName not in visited: # 若是不是目的地,則繼續向下找,這裏中轉次數要加一,而且本條路徑中已經訪問過的節點不用再訪問 visited.add(dstName) self.findFlight(flightsMap, flightsMap.get(dstName), nextTotalPrice, finalDst, stops + 1, stopLimit, visited) visited.remove(dstName) def constructGraph(self, flights): flightsMap = {} for flight in flights: # 將航線按照出發城市一一加入圖中 src = flight[0] dst = flight[1] price = flight[2] node = flightsMap.get(src, GraphNode(src)) node.addFlight(dst, price) flightsMap[src] = node return flightsMap