Submission #1173714

#TimeUsernameProblemLanguageResultExecution timeMemory
1173714qrnEvacuation plan (IZhO18_plan)C++20
0 / 100
182 ms74700 KiB
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
using namespace std;
// using namespace __gnu_pbds;

// template<class T>
// using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define SPEED                     \
    ios_base::sync_with_stdio(0); \
    cin.tie(NULL);                \
    cout.tie(NULL);

#define pb push_back
#define ins insert
#define fi first
#define se second

#define endl "\n"
#define ALL(x) x.begin(), x.end()
#define sz(x) x.size()
#define intt long long

const intt mod = 1e9 + 7;
const intt base = 31;
const intt inf = 1e9;
const intt mxN = 2e5 + 5;
const intt L = 21;

vector<vector<pair<intt,intt>>> graph, tgraph;
vector<vector<intt>> up, mini;
vector<intt> npp(mxN), used(mxN), dis(mxN), in(mxN), out(mxN), depth(mxN);
intt n, m, timer;

void dfs(intt node, intt parent) {
    in[node] = timer++;
    up[0][node] = parent;
    for(intt i = 1; i <= L; i++) {
        up[i][node] = up[i-1][up[i-1][node]];
    }
    
    for(auto u : tgraph[node]) {
        if(u.fi != parent) {
            depth[u.fi] = depth[node] + 1;
            dfs(u.fi, node);
        }
    }
    out[node] = timer++;
}

bool isata(intt a, intt b) {
    return in[a] <= in[b] && out[a] >= out[b];
}

intt lca(intt a, intt b) {
    if(isata(a,b)) return a;
    if(isata(b,a)) return b;
    
    for(intt i = L - 1; i >= 0; i--) {
        if(!isata(up[i][a], b)) {
            a = up[i][a];
        }
    }
    return up[0][a];
}


intt bl(intt node, intt k) {
    intt ret = inf;
    for(intt i = L - 1; i >= 0; i--) {
        if(((1 << i) & k)) {
            ret = min(ret, mini[i][node]);
            node = up[i][node];
        }
    }
    return ret;
}


void bfs(intt node) {
    for(intt i = 1; i <= n; i++) {
        dis[i] = inf;
    }
    dis[node] = 0;
    
    queue<intt> q;
    q.push(node);
    while(not q.empty()) {
        intt cur = q.front();
        q.pop();
        if(used[cur]) continue;
        used[cur] = 1;
        
        for(auto u : graph[cur]) {
            if(dis[u.fi] > dis[cur] + u.se) {
                dis[u.fi] = dis[cur] + u.se;
                q.push(u.fi);
            }
        }
    }
    for(intt i = 1; i <= n; i++) --dis[i];
}

struct DSU{
    vector<intt> parent, sze;
    DSU(intt n) {
        parent.resize(n + 1);
        sze.resize(n + 1);
        for(intt i = 1; i <= n; i++){
            parent[i] = i;
            sze[i] = 1;
        }
    }
    
    intt root(intt x) {
        if(parent[x] == x) return x;
        else return parent[x] = root(parent[x]);
    }
    
    void unite(intt a, intt b) {
        a = root(a);
        b = root(b);
        if(a == b) return;
        
        if(sze[a] < sze[b]) swap(a, b);
        parent[b] = a;
        sze[a] += sze[b];
    }
};

vector<array<intt,3>> edges;

bool cmp(array<intt,3> &a, array<intt,3> &b) {
    if(a[2] == b[2]) return a[1] < b[1];
    return a[2] > b[2];
}

intt W = 0;
void kruskal() {
    DSU dsu(n + 1);
    sort(ALL(edges), cmp);
    
    for(auto e : edges) {
        if(dsu.root(e[0]) != dsu.root(e[1])) {
            dsu.unite(e[0], e[1]);
            tgraph[e[0]].pb({e[1], e[2]});
            tgraph[e[1]].pb({e[0], e[2]});
            W += e[2];
        }
    }
}



void solve() {
    cin >> n >> m;
    graph.assign(n + 1, vector<pair<intt,intt>>{});
    tgraph.assign(n + 1, vector<pair<intt,intt>>{});
    up.assign(L + 1, vector<intt>(n + 1, 0ll));
    mini.assign(L + 1, vector<intt>(n + 1, inf));
    
    for(intt i = 1; i <= m; i++) {
        intt a, b, w;
        cin >> a >> b >> w;
        graph[a].pb({b, w});
        graph[b].pb({a, w});
    }
    
    intt k;
    cin >> k;
    for(intt i = 0; i < k; i++){
        intt x; cin >> x;
        npp[x] = 1;
        graph[0].pb({x, 1});
    }
    bfs(0);
    
    // for(intt i = 1; i <= n; i++) {
    //     cout << dis[i] << " ";
    // }
    // cout << endl;
    
    
    for(intt i = 1; i <= n; i++) {
        for(auto u : graph[i]) {
            intt w = min(dis[i], dis[u.fi]);
            edges.pb({u.fi, i, w});
        }
    }
    kruskal();
    
    dfs(1, 1);
   
    for(intt i = 1; i <= n; i++) {
        if(tgraph[i].empty()) continue;
        for(auto u : tgraph[i]) {
            if(u.fi == up[0][i]) {
                mini[0][i] = u.se;
            }
        }
    }
    
    for(intt i = 1; i <= L; i++) {
        for(intt node = 1; node <= n; node++){
            mini[i][node] = min(mini[i-1][node], mini[i-1][up[i-1][node]]);
        }
    }
    
    intt q;
    cin >> q;
    while(q--) {
        intt a, b;
        cin >> a >> b;
        intt l = lca(a, b);
        intt solans = bl(a, depth[a] - depth[l]);
        intt sagans = bl(b, depth[b] - depth[l]);
        cout << min(solans, sagans) << endl;
    }
}

signed main() {
    SPEED;
    intt tst = 1;
    // cin >> tst;
    while (tst--) {
        solve();
    }
}
#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...