LeetCode -- 787. K 站中转内最便宜的航班

发布时间 2023-07-13 10:26:59作者: 深渊之巅

 有边数限制的最短路

1、动态规划

f[i][j]表示恰好通过i次,从起点到大j这个点的最短路径。

class Solution {
private:
    static constexpr int INF = 10000 * 101 + 1;

public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
        vector<vector<int>> f(k + 2, vector<int>(n, INF));
        f[0][src] = 0;
        for (int t = 1; t <= k + 1; ++t) {
            for (auto&& flight: flights) {
                int j = flight[0], i = flight[1], cost = flight[2];
                f[t][i] = min(f[t][i], f[t - 1][j] + cost);
            }
        }
        int ans = INF;
        for (int t = 1; t <= k + 1; ++t) {
            ans = min(ans, f[t][dst]);
        }
        return (ans == INF ? -1 : ans);
    }
};

2、bellman_ford算法

class Solution {

int dist[110 * 50], backup[110 * 50];
int idx = 0;
struct Node {
    int a, b, w;
}edge[110 * 50];

public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
        int m = flights.size();
        memset(dist, 0x3f, sizeof dist);
        dist[src] = 0;

        for(auto &it : flights) {
            edge[idx ++ ] = {it[0], it[1], it[2]};
        }

        auto bell = [&]() {
            for(int i = 0; i <= k; i ++ ) {
                memcpy(backup, dist, sizeof dist);
                for(int j = 0; j < m; j ++ ) {
                    int a = edge[j].a, b = edge[j].b, w = edge[j].w;
                    dist[b] = min(dist[b], backup[a] + w);
                }
            }
        };

        bell();

        if(dist[dst] > 0x3f3f3f3f / 2) return -1;
        return dist[dst];

    }
};