787. Cheapest Flights Within K Stops

https://leetcode.com/problems/cheapest-flights-within-k-stops/description/

DFS (slow)

class Solution {
public:
    vector<vector<pair<int,int>>> v;     // city: <connected city, price>
    vector<bool> visited;
    int res = INT_MAX;

    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        v = vector<vector<pair<int,int>>>(n);
        visited = vector<bool>(n, false);

        for (const auto& flight : flights)
            v[flight[0]].push_back( { flight[1], flight[2] });

        visited[src] = true;
        dfs(n, src, dst, K+1, 0);
        return res == INT_MAX ? -1 : res;
    }

    void dfs(int n, int cur, int dst, int K, int cost) {
        if (cur == dst) {
            res = min(res, cost);
            return;
        }
        if (cost >= res)    return;     // if cost >= res, no point to search further
        if (K == 0) return;

        for (const auto& pCityPrice : v[cur]) {
            if (!visited[pCityPrice.first]) {
                visited[cur] = true;
                dfs(n, pCityPrice.first, dst, K-1, cost + pCityPrice.second);
                visited[cur] = false;
            }
        }
    }
};

BFS (seems not able to use BFS as below, we may have to record each path. Looks like paths in BFS is not independent, we can‘t use BFS. In this case, if A->B->C and A->C, we are not able to determine cost[C] unless we keep track the path to C. Then we may use DFS directly.)

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<vector<pair<int,int>>> v = vector<vector<pair<int,int>>>(n);
        vector<int> cost = vector<int>(n, -1);

        for (const auto& flight : flights)
            v[flight[0]].push_back( { flight[1], flight[2] });

        queue<int> q;
        q.push(src);
        cost[src] = 0;

        int stop = 0;
        while (!q.empty()) {
            if (stop++ > K)
                break;

            int qsz = q.size();
            while (qsz-- > 0) {
                int cur = q.front(); q.pop();
                for (const auto& pCityPrice : v[cur]) {
                    int curDest = pCityPrice.first;
                    if (cost[curDest] == -1 || cost[curDest] > cost[cur] + pCityPrice.second) {
                        q.push(curDest);
                        cost[curDest] = cost[cur] + pCityPrice.second;
                    }
                }
            }
        }
        return cost[dst];
    }
};

Expand stops from src.

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<vector<pair<int,int>>> v = vector<vector<pair<int,int>>>(n);

        for (const auto& flight : flights)
            v[flight[0]].push_back( { flight[1], flight[2] });

        vector<vector<int>> dp(n, vector<int>(K+1, INT_MAX));

        for (const auto& pCityPrice : v[src]) {
            int curDest = pCityPrice.first;
            int curPrice = pCityPrice.second;
            dp[curDest][0] = min(dp[curDest][0], curPrice);
        }
        for (int k = 1; k <= K; k++) {
            for (int i = 0; i < n; i++) {
                if (dp[i][k-1] == INT_MAX)   continue;
                for (const auto& pCityPrice : v[i]) {
                    int curDest = pCityPrice.first;
                    int curPrice = pCityPrice.second;
                    dp[curDest][k] = min(dp[curDest][k], dp[i][k-1] + curPrice);
                }
            }
        }
        int res = INT_MAX;
        for (int k = 0; k <= K; k++)
            res = min(res, dp[dst][k]);
        return res == INT_MAX ? -1 : res;
    }
};

Think backward, expand stops from dst.

class Solution {
public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
        vector<int> bestfrom(n, INT_MAX);     // Current best from n to dst

        for (const auto& flight : flights) {        // non-stop from each city to dst
            if (flight[1] == dst)
                bestfrom[flight[0]] = min(bestfrom[flight[0]], flight[2]);
        }
        // from each city to dst with one more stop.
        // say we know bestfrom[A] is reachable, now if we find price[B->A] + bestfrom[A] < bestfrom[B],
        // we find a better route from B to dst.
        for (int k = 1; k <= K; k++) {
            for (const auto& flight : flights) {
                if (bestfrom[flight[1]] != INT_MAX)
                    bestfrom[flight[0]] = min(bestfrom[flight[0]], bestfrom[flight[1]] + flight[2]);
            }
        }
        return bestfrom[src] == INT_MAX ? -1 : bestfrom[src];
    }
};

原文地址:https://www.cnblogs.com/JTechRoad/p/8978075.html

时间: 2024-11-13 05:53:42

787. Cheapest Flights Within K Stops的相关文章

Dijkstra’s Shortest Path Algorithm / LeetCode 787. Cheapest Flights Within K Stops

Dijkstra’s Shortest Path Algorithm 实现详见:https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ 需要注意的是,priority_queue并无法更新内部的元素,因此我们更新dist的同时,直接把新的距离加入pq即可.pq里虽然有outdated的dist,但是由于距离过长,他们并不会更新dist. // If there is sho

[Swift]LeetCode787. K 站中转内最便宜的航班 | 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 flights, together with starting city src and the destination dst, your task is to find the cheapest price from src 

Within K stops 最短路径 Cheapest Flights Within K Stops

2018-09-19 22:34:28 问题描述: 问题求解: 本题是典型的最短路径的扩展题,可以使用Bellman Ford算法进行求解,需要注意的是在Bellman Ford算法的时候需要额外申请一个数组来保存变量. public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) { int[] dist = new int[n]; for (int i = 0; i < n; i++) dist[i

算法与数据结构基础 - 广度优先搜索(BFS)

BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数据结构基础 - 队列(Queue) 最直观的BFS应用是图和树的遍历,其中图常用邻接表或矩阵表示,例如 LeetCode题目 690. Employee Importance: // LeetCode 690. Employee Importance/* class Employee { publi

【LeetCode】动态规划(下篇)

[600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offers [639] Decode Ways II [646] Maximum Length of Pair Chain [647] Palindromic Substrings [650] 2 Keys Keyboard [651] 4 Keys Keyboard [656] Coin Path [6

【LeetCode】堆 heap(共31题)

[23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无序数组中最小/大的K个数) 给了一个无序数组,可能有重复数字,找到第 k 个最大的元素并且返回这个元素值. 题解:直接用直接用个堆保存数组中最大的 K 个数.时间复杂度是 O(NlogK). 1 //时间复杂度是 O(NlogK), 用堆辅助. 2 class Solution { 3 public: 4 int findKthLargest(vector<int>

【LeetCode】动态规划(上篇共75题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [5] Longest Palindromic Substring 给一个字符串,需要返回最长回文子串 解法:dp[i][j] 表示 s[i..j] 是否是回文串,转移方程是 dp[i][j] = 1 (if dp[i+1][j-1] = 1 && s[i] == s[j]),初始化条件是 if (s[i] == s[j] && (i == j

【LeetCode】动态规划(下篇共39题)

[600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offers [639] Decode Ways II [646] Maximum Length of Pair Chain [647] Palindromic Substrings [650] 2 Keys Keyboard [651] 4 Keys Keyboard [656] Coin Path [6

【LeetCode】BFS(共43题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [101]Symmetric Tree 判断一棵树是不是对称. 题解:直接递归判断了,感觉和bfs没有什么强联系,当然如果你一定要用queue改写的话,勉强也能算bfs. // 这个题目的重点是 比较对象是 左子树的左儿子和右子树的右儿子, 左子树的右儿子和右子树的左儿子.不要搞错. // 直接中序遍历的话会有错的情况,最蠢的情况是数字标注改一改.. 1 /** 2