Submission #1293633

#TimeUsernameProblemLanguageResultExecution timeMemory
12936331otaVoting Cities (NOI22_votingcity)C++20
100 / 100
268 ms61028 KiB
#include <bits/stdc++.h>
using namespace std;

#define endl "\n"
#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
#define entire(x) (x).begin(), (x).end()

const int inf = 9e18;

int32_t main(){
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int n, e, k, t = 5; cin >> n >> e >> k;
    vector<int> good(n, false);
    for (int i = 0, vc; i < k; i++) cin >> vc, good[vc] = true;

    vector<vector<pii>> inv(n);
    for (int i = 0; i < e; i++){
        int u, v, w; cin >> u >> v >> w;
        inv[v].push_back(pii{u, w}); // reversed edge
    }

    vector<vector<int>> c(n, vector<int>((1ll << t), inf)); // node, mask
    vector<vector<vector<pii>>> adj(n, vector<vector<pii>>((1ll << t)));
    
    for (int u = 0; u < n; u++) for (auto [v, w] : inv[u]){
        for (int mask = 0; mask < (1ll << t); mask++){
            for (int p = 0; p <= t; p++) {
                if (p == 0) adj[u][mask].push_back(pii{(v << t), w});
                else adj[u][mask].push_back(pii{(1ll << (p-1)) + (v << t), (w / 10) * (10 - p)});
            }
        }
    }

    priority_queue<pii, vector<pii>, greater<pii>> pq; // reach toll, masked node
    for (int s = 0; s < n; s++){
        if (!good[s]) continue;
        pq.push(pii{0ll, (s << t)});
    }

    while (!pq.empty()){
        auto [toll, mnode] = pq.top(); pq.pop();
        int mask = mnode % (1ll << t), node = (mnode >> t);
        if (c[node][mask] <= toll) continue;
        else c[node][mask] = toll;
        for (auto [tu, w] : adj[node][mask]){
            if ((tu & mask) != 0) continue;
            pq.push(pii{toll + w, tu | mask});
        }
    }

    int q; cin >> q;
    while (q--){
        int node, ans = inf; cin >> node;
        vector<int> p(t);
        for (int i = 0; i < t; i++) cin >> p[i];
        for (int mask = 0; mask < (1ll << t); mask++){
            if (c[node][mask] >= inf) continue;
            int price = 0, isgood = 1;
            for (int i = 0; i < t; i++) if ((1ll << i) & mask) {
                if (p[i] == -1) isgood = -1;
                else price += p[i];
            }
            if (isgood == -1) continue;
            else ans = min(ans, c[node][mask] + price);
        }

        if (ans >= inf) cout << -1 << endl;
        else cout << ans << endl;
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...