雙調路徑

雙調路徑node

思路:咱們能夠容易想到,經過不一樣的邊到達某個點的時間和金錢是不同的,這是難點。咱們發現點數n = 100,權值t,c = 100,若是咱們分別維護時間權值爲x時,到達該城市的最少金錢是多少,即d[城市][時間]  = 金錢,由於 n = 100, t,c = 100,說明咱們須要維護 n*t 個點的值,則邊數爲 n * t * m = 3e6,咱們能夠用spfa解決。ios

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>

using namespace std;

#define ll long long
#define pb push_back
#define fi first
#define se second

const int INF = 2e4;

struct node {
    int v, c, t;
};

void SPFA(int n, int S, int T, vector<vector<node> >& E) {
    int _size = n * 100;
    vector<vector<bool> > vis(n + 1, vector<bool>(_size + 100, 0));
    vector<vector<int> > d(n + 1, vector<int>(_size + 100, INF));
    queue<pair<int, int> > que;
    vis[S][0] = true;
    d[S][0] = 0;
    que.push(make_pair(S, 0));

    while (!que.empty()) {
        int u = que.front().fi;
        int w = que.front().se;
        que.pop();
        vis[u][w] = false;
        for (auto e : E[u]) {
            if (w + e.t > n * 100)
                continue;  //最多 n * 100 的時間消耗,沒有限制,則d[x][∞]會一直更新
            if (d[e.v][w + e.t] > d[u][w] + e.c) {
                d[e.v][w + e.t] = d[u][w] + e.c;
                if (!vis[e.v][w + e.t]) {
                    vis[e.v][w + e.t] = true;
                    que.push(make_pair(e.v, w + e.t));
                }
            }
        }
    }
    int ans = 0;
    int Min = INF;
    for (int i = 0; i <= n * 100; ++i) {
        if (d[T][i] < Min) {
            ++ans;
            Min = d[T][i];
        }
    }
    printf("%d\n", ans);
    // cout << "this" << endl;
}

void solve() {
    int n, m, S, T;
    scanf("%d%d%d%d", &n, &m, &S, &T);
    vector<vector<node> > E(n + 1);
    int u, v, c, t;
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d%d", &u, &v, &c, &t);
        E[u].pb({ v, c, t });
        E[v].pb({ u, c, t });
    }

    SPFA(n, S, T, E);
}

int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(0); cout.tie(0);
    // freopen("C:\\Users\\admin\\Desktop\\input.txt", "r", stdin);
    // freopen("C:\\Users\\admin\\Desktop\\output.txt", "w", stdout);
    solve();
    // cout << "not error" << endl;
    return 0;
}
相關文章
相關標籤/搜索