제출 #1348340

#제출 시각아이디문제언어결과실행 시간메모리
1348340vuvietEvacuation plan (IZhO18_plan)C++20
100 / 100
369 ms53112 KiB
/**
 *     Author:       trviet
 *     Studies at:   Le Hong Phong High School for the Gifted
**/

#include <bits/stdc++.h>

using namespace std;

constexpr int maxn = 1e6 + 5;
constexpr long long inf = 1e18;
typedef pair<int, int> pii;

int n, m, k, q, x[maxn], lo[maxn], hi[maxn];
long long d[maxn], res[maxn];
vector<pii> graph[maxn];

struct DisjointSets
{
    int sz;
    vector<int> lab;

    DisjointSets(int sz)
    {
        this->sz = sz;
        lab.resize(sz + 5, -1);
    }

    int findset(int u)
    {
        return lab[u] < 0 ? u : lab[u] = findset(lab[u]);
    }

    void unite(int r, int s)
    {
        r = findset(r), s = findset(s);
        if (r == s) return;
        if (lab[r] > lab[s]) swap(r, s);
        lab[r] += lab[s], lab[s] = r;
    }
};

struct Edge
{
    int u, v;
    long long w;
    bool operator < (Edge o) const {
        return w > o.w;
    }
} e[maxn], qr[maxn];

void ReadData()
{
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int u, v, w;
        cin >> u >> v >> w;
        graph[u].push_back({v, w});
        graph[v].push_back({u, w});
        e[i] = {u, v, w};
    }
    cin >> k;
    for (int i = 0; i < k; ++i)
        cin >> x[i];
    cin >> q;
    for (int i = 0; i < q; ++i)
    {
        cin >> qr[i].u >> qr[i].v;
        lo[i] = 0, hi[i] = m - 1;
    }
}

void Dijkstra()
{
    priority_queue<pair<long long, int>> pq;
    fill(d, d + 1 + n, inf);
    for (int i = 0; i < k; ++i)
        d[x[i]] = 0, pq.push({0, x[i]});
    while (!pq.empty())
    {
        int u = pq.top().second;
        pq.pop();
        for (int i = 0; i < graph[u].size(); ++i)
        {
            int v = graph[u][i].first;
            long long w = graph[u][i].second;
            if (d[v] > d[u] + w)
                d[v] = d[u] + w, pq.push({-d[v], v});
        }
    }
}

void Solve()
{
    Dijkstra();
    for (int i = 0; i < m; ++i)
    {
        int u = e[i].u, v = e[i].v;
        e[i] = {u, v, min(d[u], d[v])};
    }
    sort(e, e + m);
    int loop = __lg(m + 2) + 2;
    for (int t = 0; t < loop; ++t)
    {
        vector<vector<int>> queries(m + 5);
        for (int i = 0; i < q; ++i)
            if (lo[i] <= hi[i])
                queries[(lo[i] + hi[i]) / 2].push_back(i);

        DisjointSets dsu(n);
        for (int i = 0; i < m; ++i)
        {
            dsu.unite(e[i].u, e[i].v);
            for (int id : queries[i])
                if (dsu.findset(qr[id].u) == dsu.findset(qr[id].v)) {
                    res[id] = e[i].w, hi[id] = i - 1;
                } else {
                    lo[id] = i + 1;
                }
        }
    }
    for (int i = 0; i < q; ++i)
        cout << res[i] << "\n";
}

int main()
{
    ReadData();
    Solve();
    return 0;
}
#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...