1. 程式人生 > 其它 >森森旅遊(天梯賽)

森森旅遊(天梯賽)


首先考慮最短路,從1跑dj用現金,從n跑dj用旅行金,動態修改
因為只要求最少的現金,用multiset維護
有一個坑點,題目說的是一個現金換ai個旅行金,那就是隻能換一個現金,不能再換多了

點選檢視程式碼
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
using PII = pair<int, int>;
using LL = long long;
using PLI = pair<LL, int>;
const LL INF = 1e18;

vector<PII> G[N], rG[N];
int n, m, q, a[N];
LL dis[N], rdis[N], res[N];
bool st[N];

void dijkstra(int S, LL dis[], int op) {
    for(int i = 1; i <= n; ++ i) {
        dis[i] = INF;
        st[i] = false;
    }
    priority_queue<PLI, vector<PLI>, greater<PLI>> Q;
    Q.push({0, S});
    dis[S] = 0;
    while(!Q.empty()) {
        int u = Q.top().second;
        Q.pop();
        if(st[u]) continue;
        st[u] = true;
        if(op) {
            for(auto &[v, w] : G[u]) 
                if(dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    Q.push({dis[v], v});
                }
        }
        else {
            for(auto &[v, w] : rG[u]) {
                if(dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    Q.push({dis[v], v});
                }
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n >> m >> q;
    for(int i = 0; i < m; ++ i) {
        int u, v, c, d;
        cin >> u >> v >> c >> d;
        G[u].push_back({v, c});
        rG[v].push_back({u, d});
    }
    for(int i = 1; i <= n; ++ i) cin >> a[i];
    dijkstra(1, dis, 1);
    dijkstra(n, rdis, 0);
    multiset<LL> S;
    for(int i = 1; i <= n; ++ i) {
        if(dis[i] == INF or rdis[i] == INF) continue;
        res[i] = dis[i] + (rdis[i] + a[i] - 1) / a[i];
        S.insert(res[i]);
    }
    while(q -- ) {
        int x, v;
        cin >> x >> v;
        if(dis[x] != INF and rdis[x] != INF) { 
            auto it = S.find(res[x]);
            S.erase(it);	
            res[x] = dis[x] + (rdis[x] + v - 1) / v;
            S.insert(res[x]);
        }
        cout << *S.begin() << "\n";
    }
    return 0; 
}