787. Cheapest Flights Within K Stops题解

题目:
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 city 2 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 city 2 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 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.

题目大意:
有m个航班连接n个城市。 每场航班都从城市u开始,以价格w到达v。
现在给出所有的城市和航班,以及起始城市src和目的地dst,你的任务是找到从src到dst最便宜的价格,最多k站。 如果没有这样的路由,则输出-1。

解题思路:
看到题目的第一想法是用最短路径Dijkstra算法做,提交之后样例过了(37/41),卡在
4
[[0,1,1],[0,2,5],[1,2,1],[2,3,1]]
0
3
1
这个样例上,百度之后发现,这题的解法是BFS,晕。
记录下我的最短路径代码,BFS的正确解法之后再写了。
为什么用BFS而不是Dijkstra的原因:
因为Dijkstra是基于贪心的思想,贪心的解决方法是每一步都是最优解,就像上面的样例,K= 1 要求从0到达3只经过1个额外的节点,按照Dijkstra就会发现程序求出来的结果是无法到达,因为程序计算从0到达1是一个最优解,通过1这个最优解无法到达3的位置,而正确答案是不要求中间的位置的每一个结果都是最优解,只要是能够在指定步数内到达的最小花费就行。所以,上面的样例,正确的通过方法是0->2->3,花费为6.

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<int> step(n, 0);
        vector<int> path(n);
        vector<vector<int>> matrix(n,vector<int>(n, INT_MAX));
        vector<bool> vis(n,false);
        vector<int> dist(n, INT_MAX);
        int m = INT_MAX, index = 0;
        for(int i =0 ; i < flights.size(); i++){
            matrix[flights[i][0]][flights[i][1]] = flights[i][2];
            dist[flights[i][1]] = matrix[src][flights[i][1]];
        }
        dist[src] = 0;
        path.push_back(src);
        vis[src] = true;
        for(int i = 1; i < n; i++){
            int minset = INT_MAX;
            int tmp = src;
            for(int j = 0; j < n; j++){
                cout<<"dist["<<j<<"] = "<<dist[j]<<endl;
                if(dist[j] < minset && (!vis[j])){
                    tmp = j;
                    minset = dist[tmp];
                }
            }
   //     cout<<"dist["<<tmp<<"] = "<<dist[tmp]<<endl;
            vis[tmp] = true;
            cout<<"tmp = "<<tmp<<endl;
            for(int j = 0; j < n; j++){
                if((dist[tmp] + matrix[tmp][j] < dist[j]) && (step[tmp] < K) && ( matrix[tmp][j] < INT_MAX)){
                    cout<<"step["<<tmp<<"] = "<<step[tmp]<<endl;
                    dist[j] = dist[tmp] + matrix[tmp][j];
                    path.push_back(tmp);
                    step[j] = step[tmp]+1;
                }
            }
            if(tmp == dst)
                break;
        }
        return dist[dst] < INT_MAX ? dist[dst] : -1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值