Submission #492390

#TimeUsernameProblemLanguageResultExecution timeMemory
492390socpiteEvacuation plan (IZhO18_plan)C++14
0 / 100
219 ms31840 KiB
#include<bits/stdc++.h>
using namespace std;

#define f first
#define s second

const int maxn = 100001;
const int oo = 1e9;
const int mx2 = 18;

int st[2][mx2][maxn];
int n, m, k, q;

void build(int x){
    if(x == mx2)return;
    for(int i = 1; i <= n; i++){
        if(st[0][x-1][i] != -1){
            st[0][x][i] = st[0][x-1][st[0][x-1][i]];
            st[1][x][i] = min(st[1][x-1][i], st[1][x-1][st[0][x-1][i]]);
        }
        else{
            st[0][x][i]=-1;
            st[1][x][i]=oo;
        }
    }
    build(x+1);
}

vector<int> up;
vector<vector<pair<int, int>>> graph;
vector<vector<int>> tree;
vector<int> level;
vector<pair<int, int>> edges;
vector<int> sp;
vector<bool> locked;

struct cmp{
    bool operator()(pair<int, int> a, pair<int, int> b){
        return a.f > b.f;
    }
};

bool cmp2(pair<int, int> a, pair<int, int> b){
    if(min(sp[a.f], sp[a.s]) == min(sp[b.f], sp[b.s]))return max(sp[a.f], sp[a.s]) > max(sp[b.f], sp[b.s]);
    else return min(sp[a.f], sp[a.s]) < min(sp[a.f], sp[a.s]);
}

int Find(int x){
    if(up[x] < 0)return x;
    else{
        up[x]=Find(up[x]);
        return up[x];
    }
}

void Union(int a, int b){
    a = Find(a); b = Find(b);
    up[b]=a;
}

void addedge(pair<int, int> x){
    tree[x.f].push_back(x.s);
    tree[x.s].push_back(x.f);
}

int travelup(int &x, int dist){
    int re = oo;
    if(dist == 0)return oo;
    else{
        for(int i = 0; i < mx2; i++){
            if(dist&(1 << i)){
                re = min(re, st[1][i][x]);
                x = st[0][i][x];
            }
        }
    }
    return re;
}

void DFS(int x, int p){
    for(auto u: tree[x]){
        if(u == p)continue;
        level[u]=level[x]+1;
        st[0][0][u]=x;
        st[1][0][u]=min(sp[x], sp[u]);
        DFS(u, x);
    }
}

int gtpath(int a, int b){
    int ans = oo;
    if(level[a] > level[b])swap(a, b);
    ans = min(ans, travelup(b, level[b]-level[a]));
    if(a == b)return ans;
    for(int i = mx2-1; i >= 0; i--){
        if(st[0][i][a] != st[0][i][b]){
            ans = min(ans, st[1][i][a]);
            a = st[0][i][a];
            ans = min(ans, st[1][i][b]);
            a = st[0][i][b];
        }
    }
    return min(ans, sp[st[0][0][a]]);
}


priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    sp.assign(n+1, oo);
    graph.resize(n+1);
    locked.assign(n+1, 0);
    level.assign(n+1, 0);
    up.assign(n+1, -1);
    st[0][0][1]=-1;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        graph[a].push_back({b, c});
        graph[b].push_back({a, c});
        edges.push_back({a, b});
    }
    cin >> k;
    for(int i = 0; i < k; i++){
        int x;
        cin >> x;
        sp[x]=0;
        pq.push({0, x});
    }
    while(!pq.empty()){
        auto x = pq.top();
        pq.pop();
        if(locked[x.s])continue;
        locked[x.s]=true;
        for(auto u: graph[x.s]){
            if(sp[u.f] > u.s+sp[x.s]){
                sp[u.f] = u.s+sp[x.s];
                pq.push({sp[u.f], u.f});
            }
        }

    }
    tree.resize(n+1);
    sort(edges.begin(), edges.end(), cmp2);
    //for(int i = 1; i <= n; i++)cout << sp[i] << " ";
    //cout << endl;
    for(int i = 0; i < m; i++){
        if(Find(edges[i].f) != Find(edges[i].s)){
            Union(edges[i].f, edges[i].s);
            //cout << edges[i].f << " " << edges[i].s << endl;
            addedge(edges[i]);
        }
    }
    DFS(1, 0);
    build(1);
    cin >> q;
    for(int i = 0; i < q; i++){
        int a, b;
        cin >> a >> b;
        cout << gtpath(a, b) << "\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...