题目:
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 city
0
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 city
0
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.
思路:
一道图遍历的题目。由于要求最短路径中间经过的顶点数目不能超过K个,所以整个最短路径的跳转次数不能超过K + 1。因此我们可以通过修改Bellman-Ford算法来实现:循环K+1次,每次更新一下每条边导致的权重减少。算法的描述如下:
1)创建源顶点src到图中所有顶点的最短距离的集合,并初始化为INT_MAX,但是将源顶点的最短路径距离置为0;
2)计算最短路径,执行K + 1次遍历:对于图中的每条边,如果起点u的距离d加上边的权值w小于终点v的距离d,则更新终点v的距离值d。
这样当执行完K+1次遍历之后,如果顶点dst的距离不为INT_MAX,就说明从src到dst存在长度不超过K+1的最短路径。Bellman-Ford算法其实采用了动态规划的思想,是最简单优雅但是又最有效的算法之一。
代码:
class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
vector<int> dp(n, INT_MAX);
dp[src] = 0;
for(int z = 0; z <= K; ++z){
vector<int> temp_dp(dp);
for(auto e: flights) {
if (dp[e[0]] < INT_MAX) {
temp_dp[e[1]] = min(temp_dp[e[1]], dp[e[0]] + e[2]);
}
}
dp = temp_dp;
}
return dp[dst] == INT_MAX ? -1 : dp[dst];
}
};