제출 #1357224

#제출 시각아이디문제언어결과실행 시간메모리
1357224Born_To_LaughEvacuation plan (IZhO18_plan)C++17
100 / 100
228 ms45648 KiB
// Born_To_Laugh - Hughie Do
#include <bits/stdc++.h>
#define alle(AC) AC.begin(), AC.end()
#define fi first
#define se second
using namespace std;
typedef long long ll;
[[maybe_unused]] const int MOD = 998244353, INF = 1e9 + 7;
const int maxn = 1e5 + 10;

struct DSU
{
    int n;
    vector<int> par, sz;
    void init(int len){
        n = len;
        par.assign(n + 1, 0);
        sz.assign(n + 1, 1);
        for(int i=1; i<=n; ++i) par[i] = i;
    }
    int headset(int x){
        if(x == par[x]) return x;
        return par[x] = headset(par[x]);
    }
    void unionset(int a, int b){
        a = headset(a);
        b = headset(b);
        if(a == b) return;
        if(sz[a] < sz[b]) swap(a, b);
        par[b] = a;
        sz[a] += sz[b];
    }
    bool sameset(int a, int b){
        return headset(a) == headset(b);
    }
};//ok

int n, m, k, q;
vector<pair<int, int>> adj[maxn];
vector<pair<pair<int, int>, int>> edges;
vector<pair<int, int>> mstadj[maxn];
int binlift[maxn][20], val[maxn][20], dep[maxn];//min
vector<int> npps;
DSU dsu;
vector<int> dijkstra(){
    vector<int> dist(n + 1, INF);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
    for(auto &elm: npps){
        dist[elm] = 0;
        pq.push({0, elm});
    }
    while(!pq.empty()){
        int x = pq.top().se;
        int d = pq.top().fi;
        pq.pop();
        if(d > dist[x]) continue;
        for(auto &elm: adj[x]){
            if(dist[elm.fi] > d + elm.se){
                dist[elm.fi] = d + elm.se;
                pq.push({d + elm.se, elm.fi});
            }
        }
    }
    return dist;
}//ok
void dfs(int a, int par){
    for(auto &sth: mstadj[a]){
        int elm = sth.fi, wei = sth.se;
        if(elm == par) continue;
        binlift[elm][0] = a;
        val[elm][0] = wei;
        for(int i=1; i<20; ++i){
            binlift[elm][i] = binlift[binlift[elm][i - 1]][i - 1];
            val[elm][i] = min(val[elm][i - 1], val[binlift[elm][i - 1]][i - 1]);
        }
        dep[elm] = dep[a] + 1;
        dfs(elm, a);
        // cout << a << ' ' << elm << ' ' << wei << '\n';
    }
}
int lca(int a, int b){
    if(dep[a] < dep[b]) swap(a, b);
    int k = dep[a] - dep[b];
    for(int i=19; i>=0; --i){
        if(k & (1 << i)) a = binlift[a][i];
    }
    if(a == b) return a;
    for(int i=19; i>=0; --i){
        if(binlift[a][i] != binlift[b][i]){
            a = binlift[a][i];
            b = binlift[b][i];
        }
    }
    return binlift[a][0];
}
int ope(int a, int b){
    int c = lca(a, b);
    int ans = INF;
    for(int i=19; i>=0; --i){
        if(dep[binlift[a][i]] >= dep[c]){
            ans = min(ans, val[a][i]);
            a = binlift[a][i];
        }
    }
    for(int i=19; i>=0; --i){
        if(dep[binlift[b][i]] >= dep[c]){
            ans = min(ans, val[b][i]);
            b = binlift[b][i];
        }
    }
    return ans;
}
void solve(){
    cin >> n >> m;
    dsu.init(n);
    for(int i=1; i<=m; ++i){
        int a, b, w;cin >> a >> b >> w;
        adj[a].push_back({b, w});
        adj[b].push_back({a, w});
        edges.push_back({{a, b}, 0});
    }
    cin >> k;
    for(int i=1; i<=k; ++i){
        int x;cin >> x;
        npps.push_back(x);
    }

    vector<int> dist = dijkstra();

    for(auto &elm: edges) elm.se = min(dist[elm.fi.fi], dist[elm.fi.se]);

    sort(alle(edges), [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){
        return a.se > b.se;
    });
    for(auto &elm: edges){
        if(dsu.sameset(elm.fi.fi, elm.fi.se)) continue;
        mstadj[elm.fi.fi].push_back({elm.fi.se, elm.se});
        mstadj[elm.fi.se].push_back({elm.fi.fi, elm.se});
        dsu.unionset(elm.fi.fi, elm.fi.se);
    }
    dep[1] = 1;
    dfs(1, -1);
    cin >> q;
    while(q--){
        int a, b;cin >> a >> b;
        cout << ope(a, b) << '\n';
    }
}
signed main(){
    // freopen("inp.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…