Submission #1348254

#TimeUsernameProblemLanguageResultExecution timeMemory
1348254vuvietEvacuation plan (IZhO18_plan)C++20
22 / 100
173 ms39440 KiB
/**
 *     Author:       trviet
 *     Studies at:   Le Hong Phong High School for the Gifted
**/

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 2e5 + 5, Log = 17;
constexpr long long inf = 1e18;
typedef pair<int, int> pii;

int n, m, k, q, h[N], x[N], up[Log][N];
long long d[N], mi[Log][N];
vector<pii> graph[N], tree[N];

int GetBit(int x, int k)
{
    return (x >> k) & 1;
}

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[N], qr[N];

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;
}

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 DFSVisit(int u, int p, long long d)
{
    up[0][u] = p, mi[0][u] = d;
    for (int k = 1; k < Log; ++k)
    {
        up[k][u] = up[k - 1][up[k - 1][u]];
        mi[k][u] = min(mi[k - 1][u], mi[k - 1][up[k - 1][u]]);
    }
    for (int i = 0; i < tree[u].size(); ++i)
    {
        int v = tree[u][i].first;
        long long w = tree[u][i].second;
        if (v != p)
            h[v] = h[u] + 1, DFSVisit(v, u, w);
    }
}

long long calc(int u, int v)
{
    long long res = min(d[u], d[v]);
    if (h[u] < h[v]) swap(u, v);
    for (int k = Log - 1; k >= 0; --k)
        if (GetBit(h[u] - h[v], k))
            res = min(res, mi[k][u]), u = up[k][u];
    if (u == v) return res;
    for (int k = Log - 1; k >= 0; --k)
        if (up[k][u] != up[k][v])
        {
            res = min({res, mi[k][u], mi[k][v]});
            u = up[k][u], v = up[k][v];
        }
    res = min({res, mi[0][u], mi[0][v]});
    return res;
}

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);
    DisjointSets dsu(n + 5);
    for (int i = 0; i < m; ++i)
    {
        int u = e[i].u, v = e[i].v, w = e[i].w;
        if (dsu.findset(u) != dsu.findset(v))
        {
            tree[u].push_back({v, w});
            tree[v].push_back({u, w});
            dsu.unite(u, v);
        }
    }
    for (int i = 1; i <= n; ++i)
        if (h[i] == 0)
            DFSVisit(i, 0, inf);
    for (int i = 0; i < q; ++i)
        cout << calc(qr[i].u, qr[i].v) << "\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...