제출 #1348451

#제출 시각아이디문제언어결과실행 시간메모리
1348451thgammiEvacuation plan (IZhO18_plan)C++20
100 / 100
281 ms70084 KiB
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll INF=1e18;

int find_root(int x, vector<int> &p){
    if(p[x]==x) return x;
    return p[x]=find_root(p[x],p);
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n,m; cin>>n>>m;
    vector<vector<pair<int,int>>> g(n+1);
    vector<int> eu(m),ev(m);
    vector<int> ew(m);

    for(int i=0;i<m;i++){
        cin>>eu[i]>>ev[i]>>ew[i];
        g[eu[i]].push_back({ev[i],ew[i]});
        g[ev[i]].push_back({eu[i],ew[i]});
    }

    int k; cin>>k;
    vector<int> danger(k);
    for(int i=0;i<k;i++) cin>>danger[i];

    vector<ll> d(n+1,INF);
    priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> pq;

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

    while(!pq.empty()){
        pair<ll,int> cur=pq.top(); pq.pop();
        ll du=cur.first;
        int u=cur.second;
        if(du!=d[u]) continue;
        for(int i=0;i<(int)g[u].size();i++){
            int v=g[u][i].first;
            ll w=g[u][i].second;
            if(d[v]>du+w){
                d[v]=du+w;
                pq.push({d[v],v});
            }
        }
    }

    vector<ll> val(m);
    for(int i=0;i<m;i++){
        val[i]=min(d[eu[i]],d[ev[i]]);
    }

    vector<int> id(m);
    for(int i=0;i<m;i++) id[i]=i;

    sort(id.begin(),id.end(),[&](int a,int b){
        return val[a]>val[b];
    });

    vector<int> parent(n+1),sz(n+1,1);
    for(int i=1;i<=n;i++) parent[i]=i;

    vector<vector<pair<int,ll>>> tree(n+1);

    for(int i=0;i<m;i++){
        int e=id[i];
        int u=eu[e], v=ev[e];
        int ru=find_root(u,parent);
        int rv=find_root(v,parent);
        if(ru!=rv){
            if(sz[ru]<sz[rv]) swap(ru,rv);
            parent[rv]=ru;
            sz[ru]+=sz[rv];

            tree[u].push_back({v,val[e]});
            tree[v].push_back({u,val[e]});
        }
    }

    int LOG=20;
    vector<vector<int>> up(n+1,vector<int>(LOG));
    vector<vector<ll>> mn(n+1,vector<ll>(LOG,INF));
    vector<int> depth(n+1,0);

    for(int i=1;i<=n;i++){
        for(int j=0;j<LOG;j++){
            up[i][j]=i;
            mn[i][j]=INF;
        }
    }

    for(int start=1;start<=n;start++){
        if(depth[start]!=0) continue;

        queue<int> q;
        q.push(start);
        depth[start]=1;
        up[start][0]=start;

        while(!q.empty()){
            int u=q.front(); q.pop();
            for(int i=0;i<(int)tree[u].size();i++){
                int v=tree[u][i].first;
                ll w=tree[u][i].second;

                if(v==up[u][0]) continue;
                if(depth[v]!=0) continue;

                depth[v]=depth[u]+1;
                up[v][0]=u;
                mn[v][0]=w;

                for(int j=1;j<LOG;j++){
                    int mid=up[v][j-1];
                    if(mid==v){
                        up[v][j]=v;
                        mn[v][j]=mn[v][j-1];
                    }else{
                        up[v][j]=up[mid][j-1];
                        mn[v][j]=min(mn[v][j-1],mn[mid][j-1]);
                    }
                }

                q.push(v);
            }
        }
    }

    int Q; cin>>Q;
    while(Q--){
        int u,v; cin>>u>>v;
        ll res=INF;

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

        int diff=depth[u]-depth[v];
        for(int i=0;i<LOG;i++){
            if(diff>>i & 1){
                res=min(res,mn[u][i]);
                u=up[u][i];
            }
        }

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

        cout<<res<<"\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...