Submission #1183576

#TimeUsernameProblemLanguageResultExecution timeMemory
1183576nguyenkhangninh99Evacuation plan (IZhO18_plan)C++20
22 / 100
4093 ms22016 KiB

#include<bits/stdc++.h>
#include<fstream>
#pragma GCC optimize("Ofast,O3,unroll-loops")
#pragma GCC target("avx2")

using namespace std;

#define int long long

const int maxn = 2e5 + 5;

//dsu rollback + parallel binary search

struct DSU{
    vector<int> par, trace;
    stack<pair<int, int>> st;
    
    void init(){
        trace.push_back(0);
        par.resize(maxn);
        for (int i = 1; i < maxn; i++) par[i] = i;
    }

    int find(int u){
        return (par[u] == u) ? u : find(par[u]);
    }
    void merge(int x, int y){
        int u = find(x);
        int v = find(y);
        if (u != v){
            st.push({u, v});
            par[v] = u;
        }
    }
    void set(){
        trace.push_back(st.size());
    }
    void redo(){
        while (st.size() > trace.back()){
            int u = st.top().first, v = st.top().second;
            st.pop();
            par[v] = v;
        }
        if (trace.back() > 0) trace.pop_back();
    }
} dsu;

int ans[maxn], s[maxn], t[maxn], ok[maxn];
vector<pair<int, int>> adj[maxn];
vector<int> comp, all;

void solve(int l, int r, vector<int>& cur){
    if(l == r) for(int i: cur) ans[i] = l;
    else{
        dsu.set();
        int mid = (l + r) / 2;
        for(int i = l; i <= mid; i++) ok[comp[i]] = 1;

        for(int i = l; i <= mid; i++){
            for(auto [v, w]: adj[comp[i]]){
                if(ok[v]) dsu.merge(comp[i], v);
            }
        }

        vector<int> le, ri;
        for(int i: cur){
            if(dsu.find(s[i]) == dsu.find(t[i])) le.push_back(i);
            else ri.push_back(i);
        }

        if(mid < r && ri.size()) solve(mid + 1, r, ri);

        for(int i = l; i <= mid; i++) ok[comp[i]] = 0;
        dsu.redo();

        if(le.size()) solve(l, mid, le);
    }
    
}
signed main(){
    ios_base::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);

    int n, m; cin >> n >> m;

    vector<int> d(n + 1, 1e9);

    for(int i = 1; i <= m; i++){
        int u, v, w; cin >> u >> v >> w;
        adj[u].push_back({v, w}); 
        adj[v].push_back({u, w});
    }

    int k; cin >> k;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; 

    for(int i = 0; i < k; i++){
        int x; cin >> x;
        d[x] = 0; 
        pq.push({0, x});
    }

    while(!pq.empty()){
        auto [curw, u] = pq.top(); 
        pq.pop();
        if(d[u] != curw) continue;
        for(auto [v, w]: adj[u]){
            if(d[v] > curw + w){
                d[v] = curw + w;
                pq.push({d[v], v});
            }
        }
    }

    for(int i = 1; i <= n; i++) comp.push_back(i);
    sort(comp.begin(), comp.end(), [&](int x, int y){
        return d[x] > d[y];
    });

    int q; cin >> q;
    for(int i = 0; i < q; i++){
        cin >> s[i] >> t[i];
        all.push_back(i);
    }
    
    dsu.init();

    solve(0, n - 1, all);

    for(int i = 0; i < q; i++) cout << d[comp[ans[i]]] << "\n";
}
#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...