제출 #440102

#제출 시각아이디문제언어결과실행 시간메모리
440102JovanBEvacuation plan (IZhO18_plan)C++17
100 / 100
882 ms54560 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

const int MAXN = 100000;
const int INF = 1000000000;
const int MXLOG = 18;

struct Edge{
    int a, b, c;
    bool operator <(const Edge &x){
        return c > x.c;
    }
};

vector <Edge> edges;

int dist[MAXN+5];
vector <pair <int, int>> graf[MAXN+5];

struct DSU{
    int n;
    int par[MAXN+5];
    int sz[MAXN+5];
    void init(int g){
        n = g;
        for(int i=1; i<=n; i++) par[i] = i;
        for(int i=1; i<=n; i++) sz[i] = 1;
    }
    int root(int x){
        if(par[x] == x) return x;
        return par[x] = root(par[x]);
    }
};

vector <pair <int, int>> drvo[MAXN+5];

int in[MAXN+5];
int out[MAXN+5];
int mnd[MAXN+5][MXLOG+1];
int par[MAXN+5][MXLOG+1];

int tjm;

void dfs(int v, int p, int gr){
    in[v] = ++tjm;
    par[v][0] = p;
    mnd[v][0] = gr;
    for(int j=1; j<=MXLOG; j++){
        par[v][j] = par[par[v][j-1]][j-1];
        mnd[v][j] = min(mnd[v][j-1], mnd[par[v][j-1]][j-1]);
    }
    for(auto c : drvo[v]) if(c.first != p) dfs(c.first, v, c.second);
    out[v] = tjm;
}

bool is_parent(int a, int b){
    return (a == 0) || (in[a] <= in[b] && out[b] <= out[a]);
}

int lca(int a, int b){
    if(is_parent(a, b)) return a;
    for(int j=MXLOG; j>=0; j--) if(!is_parent(par[a][j], b)) a = par[a][j];
    return par[a][0];
}

int main(){
    ios_base::sync_with_stdio(false), cin.tie(0);
    cout.precision(10);
    cout << fixed;

    int n, m;
    cin >> n >> m;
    for(int i=1; i<=m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        graf[a].push_back({b, c});
        graf[b].push_back({a, c});
        edges.push_back({a, b, c});
    }
    for(int i=1; i<=n; i++) dist[i] = INF;
    int plants;
    cin >> plants;
    set <pair <int, int>> q;
    while(plants--){
        int v;
        cin >> v;
        dist[v] = 0;
        q.insert({0, v});
    }
    while(!q.empty()){
        int v = q.begin()->second;
        q.erase(q.begin());
        for(auto c : graf[v]){
            if(dist[c.first] > dist[v] + c.second){
                q.erase({dist[c.first], c.first});
                dist[c.first] = dist[v] + c.second;
                q.insert({dist[c.first], c.first});
            }
        }
    }
    for(int i=0; i<m; i++){
        Edge c = edges[i];
        edges[i].c = min(dist[c.a], dist[c.b]);
    }
    sort(edges.begin(), edges.end());
    DSU dsu;
    dsu.init(n);
    for(auto edge : edges){
        int a = edge.a;
        int b = edge.b;
        int c = edge.c;
        int a1 = dsu.root(a);
        int b1 = dsu.root(b);
        if(a1 == b1) continue;
        if(dsu.sz[a1] < dsu.sz[b1]) swap(a1, b1);
        dsu.sz[a1] += dsu.sz[b1];
        dsu.par[b1] = a1;
        drvo[a].push_back({b, c});
        drvo[b].push_back({a, c});
    }
    dfs(1, 0, 0);
    int cases;
    cin >> cases;
    while(cases--){
        int a, b;
        cin >> a >> b;
        int x = lca(a, b);
        int res = dist[x];
        for(int j=MXLOG; j>=0; j--){
            if(!is_parent(par[a][j], x)){
                res = min(res, mnd[a][j]);
                a = par[a][j];
            }
        }
        if(a != x) res = min(res, mnd[a][0]);
        for(int j=MXLOG; j>=0; j--){
            if(!is_parent(par[b][j], x)){
                res = min(res, mnd[b][j]);
                b = par[b][j];
            }
        }
        if(b != x) res = min(res, mnd[b][0]);
        cout << res << "\n";
    }
    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...