제출 #1347736

#제출 시각아이디문제언어결과실행 시간메모리
1347736nxk02102010Evacuation plan (IZhO18_plan)C++20
100 / 100
387 ms94820 KiB
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F first
#define S second
const int MAX = 100100,INF = 1e18 + 7,MAXM = 2 * 100100;
int n,m,k,q;
int kk[MAX];
vector<pair<int,int>> g[MAXM];
vector<int> gr[MAXM];
int dist[MAX];
struct E{
        int u,v,w;
};
vector<E> ed;
void multi(){
        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;
        fill(dist,dist + n + 1,INF);
        for(int i = 0;i < k;i++){
                q.push({0,kk[i]});
                dist[kk[i]] = 0;
        }
        while(!q.empty()){
                auto top = q.top();q.pop();
                int u = top.S;
                int w1 = top.F;
                if(w1 != dist[u]) continue;
                for(auto &to : g[u]){
                        int v = to.F;
                        int w2 = to.S;
                        if(dist[v] > w1 + w2){
                                dist[v] = w1 + w2;
                                q.push({dist[v],v});
                        }
                }
        }
}
int p[MAX];
int find(int v){ return v == p[v] ? v : p[v] = find(p[v]); }
bool unite(int a,int b){
        a = find(a);
        b = find(b);
        if(a == b) return 0;
        p[b] = a;
        return 1;
}
void MST(){
        for(int u = 1;u <= n;u++){
                for(auto &to : g[u]){
                        int v = to.F;
                        ed.push_back({u,v,min(dist[u],dist[v])});
                }
        }
        sort(ed.begin(),ed.end(),[&](const E &a,const E &b){ return a.w > b.w; });
        for(auto &i : ed){
                if(unite(i.u,i.v)){
                        gr[i.u].push_back(i.v);
                        gr[i.v].push_back(i.u);
                }
        }
}
int f[MAX][20];
int mi[MAX][20];
int dep[MAX];
void build(int u = 1,int p = -1){
        if(p == -1) dep[u] = 1;
        f[u][0] = p;
        if(p != -1) mi[u][0] = min(dist[u],dist[p]);
        for(int i = 1;i < 20;i++){
                if(f[u][i - 1] != -1 && f[f[u][i - 1]][i - 1] != -1){
                        f[u][i] = f[f[u][i - 1]][i - 1];
                        mi[u][i] = min(mi[u][i - 1],mi[f[u][i - 1]][i - 1]);
                }
        }
        for(int v : gr[u]) if(v ^ p){
                dep[v] = dep[u] + 1;
                build(v,u);
        }
}
int lca(int a,int b){
        if(dep[a] < dep[b]) swap(a,b);
        int res = min(dist[a],dist[b]);
        for(int i = 19;i >= 0;i--) if((dep[a] - dep[b]) & (1 << i)){
                res = min(res,mi[a][i]);
                a = f[a][i];
        }
        if(a == b) return res;
        for(int i = 19;i >= 0;i--) if(f[a][i] != f[b][i]){
                res = min({res,mi[a][i],mi[b][i]});
                a = f[a][i];
                b = f[b][i];
        }
        if(f[a][0] != -1) res = min(res,mi[a][0]);
        return res;
}
signed main(){
        //freopen("exit.inp","r",stdin);
        //freopen("exit.out","w",stdout);
        ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        cin >> n >> m;
        iota(p,p + n + 1,0);
        for(int i = 1;i <= m;i++){
                int a,b,c;cin >> a >> b >> c;
                g[a].push_back({b,c});
                g[b].push_back({a,c});
        }
        cin >> k;
        for(int i = 0;i < k;i++) cin >> kk[i];
        multi();
        MST();
        for(int i = 0;i < 20;i++) for(int j = 0; j <= n;j++) f[j][i] = -1,mi[j][i] = 1e18;
        build();
//        for(int i = 1;i <= n;i++){
//                cout << i << '\n';
//                for(int j = 0; j < 20;j++){
//                        cout << f[i][j] << ' ' << mi[i][j] << '\n';
//                }
//                cout << "\n\n";
//        }
        int q;cin >> q;
        while(q--){
                int a,b;cin >> a >> b;
                cout << (lca(a,b)) << '\n';
        }
}
/*
6 5
1 2 3
2 3 4
3 4 10
3 5 1000
4 6 11
2
1 6
5
6 1
1 6
3 3
4 2
5 6
*/
#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...