제출 #1325375

#제출 시각아이디문제언어결과실행 시간메모리
1325375vlad7654Evacuation plan (IZhO18_plan)C++20
100 / 100
802 ms32140 KiB
#include <bits/stdc++.h>
using namespace std;
const int NMAX=1e5, inf=1e9;
vector<pair<int,int> > graph[NMAX+5];
vector<pair<int,int> > queries;
vector<pair<int,int> > srt;
int ans[NMAX+5], centrale[NMAX+5];
int lo[NMAX+5], hi[NMAX+5];
vector<int> queries_at_mid[NMAX+5], dist;
int n, m, k, q;
void dijkstra() {
    priority_queue<pair<int,int> > q;
    for (int i=1;i<=k;i++) {
        dist[centrale[i]]=0;
        q.push({0, centrale[i]});
    }
    while (!q.empty()) {
        int nod=q.top().second;
        q.pop();
        for (auto it:graph[nod]) {
            if (dist[it.first]>dist[nod]+it.second) {
                dist[it.first]=dist[nod]+it.second;
                q.push({-dist[it.first], it.first});
            }
        }
    }
}
struct DSU {
    vector<int> parent, status;
    void init(int n) {
        parent.assign(n+1, 0), status.assign(n+1, 0);
        for (int i=1;i<=n;i++) {
            parent[i]=i;
            status[i]=1;
        }
    }
    int find_set(int nod) {
        if (parent[nod]==nod) {
            return nod;
        }
        return parent[nod]=find_set(parent[nod]);
    }
    void unite(int nod1, int nod2) {
        nod1=find_set(nod1);
        nod2=find_set(nod2);
        if (nod1!=nod2) {
            if (status[nod1]<status[nod2]) {
                swap(nod1, nod2);
            }
            parent[nod2]=nod1;
            status[nod1]+=status[nod2];
        }
    }
};
DSU dsu;
int main() {
    cin>>n>>m;
    for (int i=1;i<=m;i++) {
        int x, y, z;
        cin>>x>>y>>z;
        graph[x].push_back({y, z});
        graph[y].push_back({x, z});
    }
    cin>>k;
    for (int i=1;i<=k;i++) {
        cin>>centrale[i];
    }
    cin>>q;
    queries.resize(q+1);
    for (int i=1;i<=q;i++) {
        cin>>queries[i].first>>queries[i].second;
        lo[i]=1;
        hi[i]=n;
    }
    dist.resize(n+1, inf);
    dijkstra();
    srt.resize(n+1);
    for (int i=1;i<=n;i++) {
        srt[i].first=dist[i];
        srt[i].second=i;
    }
    sort(srt.begin()+1, srt.end(), greater<pair<int,int> >());
    bool changed=true;
    while (changed) {
        changed=false;
        fill(queries_at_mid + 1, queries_at_mid + n + 1, vector<int>());
        for (int i=1;i<=q;i++) {
            if (lo[i]<=hi[i]) {
                changed=true;
                int mid=(lo[i]+hi[i])/2;
                queries_at_mid[mid].push_back(i);
            }
        }
        dsu.init(n);
        for (int i=1;i<=n;i++) {
            auto [d, nod]=srt[i];
            for (auto it:graph[nod]) {
                if (d<=dist[it.first]) {
                    dsu.unite(it.first, nod);
                }
            }
            for (auto it:queries_at_mid[i]) {
                if (dsu.find_set(queries[it].first)==dsu.find_set(queries[it].second)) {
                    ans[it]=i;
                    hi[it]=i-1;
                }else {
                    lo[it]=i+1;
                }
            }
        }
    }
    for (int i=1;i<=q;i++) {
        cout<<srt[ans[i]].first<<'\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...