Submission #1351033

#TimeUsernameProblemLanguageResultExecution timeMemory
1351033michael12Evacuation plan (IZhO18_plan)C++20
100 / 100
262 ms82308 KiB
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<numeric>
#include<string>
#include<stack>
#include<queue>
#include<string.h>
#include<array>
#include<climits>
#include<algorithm>
#include<cmath>
using namespace std;

#define ff first
#define ss second
#define int long long
#define pb push_back
#define endl '\n'
const int maxn = 1e5 + 2;
const int Mx = 1e12;
const int oo = 1e18;
const int LG = 20;
int dist[maxn];
vector<pair<int, int>> tree[maxn];
vector<pair<int, int>> g[maxn];
int n, m;
int up[maxn][LG];
int mn[maxn][LG];
int depth[maxn];
struct Edge{
    int u, v, w;
};
vector<Edge> edges;
void dijkstra(vector<int>& npp){
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    for(int i = 1; i <= n; i++){
        dist[i] = oo;
    }
    for(auto v : npp){
        dist[v] = 0;
        pq.push({0, v});
    }
    while(!pq.empty()){
        auto T = pq.top();
        pq.pop();
        int d = T.ff;
        int v = T.ss;
        if(d > dist[v]) continue;
        for(auto f : g[v]){
            int x = f.ff;
            int y = f.ss;
            if(dist[v] + y < dist[x]){
                dist[x] = dist[v] + y;
                pq.push({dist[x], x});
            }
        }
    }
}
vector<int> p;
vector<int> sz;    
int find(int u){
    if(u == p[u]) return u;
    return p[u] = find(p[u]);
}
bool unite(int u, int v){
    int a = find(u);
    int b = find(v);
    if(a == b) return false;
    if(sz[a] < sz[b]) swap(a, b);
    sz[a] += sz[b];
    p[b] = a;
    return true;
    
}
void build_mst(int n){
    p.resize(n + 1);
    sz.resize(n + 1);
    for(int i = 1; i <= n; i++){
        p[i] = i;
        sz[i] = 1;
    }
    sort(edges.begin(), edges.end(),
    [](Edge a, Edge b){
        return a.w > b.w;
    }
    );

    for(auto e : edges){
        if(unite(e.u, e.v)){
            tree[e.u].push_back({e.v, e.w});
            tree[e.v].push_back({e.u, e.w});
        }
    }
}
void dfs(int v, int p, int w){
    up[v][0] = p;
    mn[v][0] = w;
    for(auto t : tree[v]){
        if(t.ff == p) continue;
        depth[t.ff] = depth[v] + 1;
        dfs(t.ff, v, t.ss);

    }
}
void build_lca(){
    for(int j = 1; j < LG; j++){
        for(int i = 1; i <= n; i++){
            up[i][j] = up[up[i][j - 1]][j - 1];
            mn[i][j] = min(mn[i][j - 1], mn[up[i][j - 1]][j - 1]);
        }
    }
}
int query(int u, int v){
    int ans = (int)1e18;

    if(depth[u] < depth[v]) swap(u, v);

    for(int i = LG - 1; i >= 0; i--){
        if(depth[u] - (1 << i) >= depth[v]){
            ans = min(ans, mn[u][i]);
            u = up[u][i];
        }
    }

    if(u == v) return ans;

    for(int i = LG - 1; i >= 0; i--){
        if(up[u][i] != up[v][i]){
            ans = min(ans, mn[u][i]);
            ans = min(ans, mn[v][i]);
            u = up[u][i];
            v = up[v][i];
        }
    }

    ans = min(ans, mn[u][0]);
    ans = min(ans, mn[v][0]);

    return ans;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;

    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }
    int k;
    cin >> k;
    vector<int> npp(k);
    for(int i = 0; i < k; i++){
        cin >> npp[i];
    }
    dijkstra(npp);
    for(int i = 1; i <= n; i++){
        for(auto t : g[i]){
            if(i < t.ff){
                int nw = min(dist[i], dist[t.ff]);
                edges.pb({i, t.ff, nw});
            }
        }
    }
    build_mst(n);
    depth[1] = 0;
    dfs(1, 0, 1e18);
    build_lca();
    int T;
    cin >> T;
    while(T--){
        int a, b;
        cin >> a >> b;
        cout << query(a, b) << endl;
    }
}
#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...