【LeetCode 787】 Cheapest Flights Within K Stops

题目描述

There are n cities connected by m flights. Each flight starts from city u and arrives at v with a price w.

Now given all the cities and flights, 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

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.

思路

思路一:动态规划。遍历步数k, 每一步遍历所有路径,对上一步能够更新的点更新。时间复杂度O(K*E) ≈ O(Kn^2)
思路二:深搜 dfs。时间复杂度 O(n^(K+1))。搜索从当前点到目标点的代价。两个剪枝,如果到当前点的代价已经大于当前答案,不需要继续。一次路径中,同一个点没必要访问两次。
思路三:广搜 bfs。和动态规划的思路差不多,以步数来搜索,队列存储上一步到达的所有点以及代价,新的一步,对上一步能到达的点的代价进行更新。时间复杂度和深搜相同。

代码

动态规划

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<vector<int> > dp(K+2, vector<int>(n, INT_MAX/2));
        dp[0][src] = 0;
        
        for (int k=1; k<=K+1; ++k) {
            dp[k][src] = 0;
            for (int i=0; i<flights.size(); ++i) {
                int a = flights[i][0], b = flights[i][1], p = flights[i][2];
                dp[k][b] = min(dp[k][b], dp[k-1][a]+p);
            }
        }
        
        return dp[K+1][dst] == INT_MAX/2 ? -1 : dp[K+1][dst];
    }
};

BFS

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        unordered_map<int, vector<pair<int, int>>> mp;
        for (const auto& e : flights) {
            mp[e[0]].emplace_back(e[1], e[2]);
        }
        queue<pair<int, int> > que; // cur, price
        que.push({src, 0});
        int ans = INT_MAX/2;
        int step = 0;
        
        while(!que.empty()) {
            int size = que.size();
            while(size--) {
                int cur = que.front().first;
                int cost = que.front().second;
                que.pop();
                if (cur == dst) {
                    ans = min(ans, cost);
                    continue;
                }
                for (const auto& p : mp[cur]) {
                    if (cost + p.second > ans) continue;
                    que.push({p.first, cost+p.second});
                }
            }
            
            if (++step > K+1) break;
        }
        
        return ans == INT_MAX/2 ? -1 : ans;
    }
};

DFS

class Solution {
public:
    int ans = INT_MAX/2;
    unordered_map<int, vector<pair<int, int>>> mp;
    
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        for (const auto& e : flights) {
            mp[e[0]].emplace_back(e[1], e[2]);
        }
        vector<int> vis(n, 0);
        vis[src] = 1;
        dfs(src, dst, K, 0, vis);
        return ans == INT_MAX/2 ? -1 : ans;
    }
    
    void dfs(int cur, int dst, int step, int cost, vector<int>& vis) {
        if (cur == dst) {
            ans = cost;
            return;
        }
        if (step < 0) return;
        
        for (const auto& p : mp[cur]) {
            if (cost + p.second > ans) continue;
            if (vis[p.first]) continue;
            vis[p.first] = 1;
            dfs(p.first, dst, step-1, cost+p.second, vis);
            vis[p.first] = 0;
        }
        return;
    }
};

建图的技巧挺好的。
啊啊啊。今天阴天,连带着心情也不是很好。暴躁.jpg

发布了243 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/iCode_girl/article/details/104481697