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
.
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: The cheapest price from city0
to city2
with at most 1 stop costs 200, as marked red in the picture.
Example 2: Input: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 0 Output: 500 Explanation: The graph looks like this: The cheapest price from city0
to city2
with at most 0 stop costs 500, as marked blue in the picture.
Note:
- The number of nodes
n
will be in range[1, 100]
, with nodes labeled from0
ton
- 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.
最开始写的标准的BFS
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
"""
dp = [[9999999 for _ in range(K+2)] for _ in range(n)]
dp[src][0] = 0
dist = [[] for _ in range(n)]
for f in flights: dist[f[0]].append(f[1:])
q, qq, step, mark = [src], [], 0, [False]*n
mark[src] = True # we may need to look up a node several times
while q:
while q:
s = q.pop()
for t in dist[s]:
dp[t[0]][step+1]=min(dp[t[0]][step+1], dp[s][step]+t[1])
if not mark[t[0]]:
qq.append(t[0])
mark[t[0]] = True
q, qq = qq, q
step += 1
if step==K+1: break
m = min(dp[dst])
return m if m!=9999999 else -1
WA,其原因在于可能需要遍历1个节点多次,每次当遍历到该节点得到一个更好的值时,就需要重新遍历该节点
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
"""
dp = [[9999999 for _ in range(K+2)] for _ in range(n)]
dp[src][0] = 0
dist = [[] for _ in range(n)]
for f in flights: dist[f[0]].append(f[1:])
q, qq, step = [src], [], 0
while q:
while q:
s = q.pop()
for t in dist[s]:
# if get better solution, need to look up once again
if dp[s][step]+t[1]<dp[t[0]][step+1]:
dp[t[0]][step+1]=dp[s][step]+t[1]
qq.append(t[0])
q, qq = qq, q
step += 1
if step==K+1: break
m = min(dp[dst])
return m if m!=9999999 else -1
AC,按照次数来DP,每次根据edge更新DP数组也可以AC
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
"""
dp = [[9999999 for _ in range(K+2)] for _ in range(n)]
dp[src][0] = 0
for i in range(1,K+2):
for f in flights:
dp[f[1]][i] = min(dp[f[1]][i], dp[f[0]][i-1]+f[2])
m = min(dp[dst])
return m if m!=9999999 else -1
s=Solution()
print(s.findCheapestPrice(n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, K = 1))
print(s.findCheapestPrice(n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, K = 0))
print(s.findCheapestPrice(4,[[0,1,100],[0,2,300],[0,3,500],[1,2,100],[2,3,100]],0,3,1))
Discuss里面有dijstra + priority queue的解法
def findCheapestPrice(self, n, flights, src, dst, k):
f = collections.defaultdict(dict)
for a, b, p in flights:
f[a][b] = p
heap = [(0, src, k + 1)]
while heap:
p, i, k = heapq.heappop(heap)
if i == dst:
return p
if k > 0:
for j in f[i]:
heapq.heappush(heap, (p + f[i][j], j, k - 1))
return -1