Submission #1348134

#TimeUsernameProblemLanguageResultExecution timeMemory
1348134peanutEvacuation plan (IZhO18_plan)C++20
100 / 100
254 ms43416 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
template<class X, class Y> bool maximize (X &x, const Y &y) {return x < y ? x = y, 1 : 0;}
template<class X, class Y> bool minimize (X &x, const Y &y) {return x > y ? x = y, 1 : 0;}
const int maxn = 1e5 + 5;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int n, m, k, q;
int depth[maxn], up[maxn][20];
int val[maxn], minval[maxn][20];
pair<int, int> edges[5 * maxn];
vector<pair<int, int>> adj[maxn];
vector<int> adj2[maxn];

struct DSU {
    vector<int> par, sizes;
    DSU(int _n): par(_n+1), sizes(_n+1, 1) {iota(all(par), 0);}
    int findset(int v) {return par[v] == v ? v : par[v] = findset(par[v]);}
    bool unite(int u, int v) {
        u = findset(u), v = findset(v);
        if (u == v) return false;
        if (sizes[u] < sizes[v]) swap(u, v);
        sizes[u] += sizes[v];
        par[v] = u;
        return true;
    }
};

void dfs(int u, int p) {
    for (auto v : adj2[u]) {
        if (v == p) continue;
        depth[v] = depth[u] + 1;
        up[v][0] = u;
        minval[v][0] = min(val[u], val[v]);
        for (int i = 1; i < 20; ++i) {
            up[v][i] = up[up[v][i-1]][i-1];
            minval[v][i] = min(minval[v][i-1], minval[up[v][i-1]][i-1]);
        }
        dfs(v, u);
    }
}

int lca(int u, int v) {
    int res = min(val[u], val[v]);
    if (depth[u] < depth[v]) swap(u, v);
    int h = depth[u] - depth[v];
    for (int i = 0; i < 20; ++i) if (h >> i & 1) res = min(res, minval[u][i]), u = up[u][i];
    if (u == v) return res;
    for (int i = 19; i >= 0; --i) {
        if (up[u][i] != up[v][i]) {
            res = min({res, minval[u][i], minval[v][i]});
            u = up[u][i];
            v = up[v][i];
        }
    }
    return min(res, minval[u][0]);
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    //freopen(".INP", "r", stdin);
    //freopen(".OUT", "w", stdout);
    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int u, v, w; cin >> u >> v >> w;
        edges[i] = {u, v};
        adj[u].pb({v, w});
        adj[v].pb({u, w});
    }
    cin >> k;
    priority_queue<pair<int, int>> pq;
    for (int i = 1; i <= n; ++i) val[i] = INT_MAX;
    for (int i = 1; i <= k; ++i) {
        int x; cin >> x;
        val[x] = 0;
        pq.push({0, x});
    }
    while (!pq.empty()) {
        int d = -pq.top().fi, u = pq.top().se;
        pq.pop();
        if (d != val[u]) continue;
        for (auto v : adj[u]) {
            if (d + v.se < val[v.fi]) {
                val[v.fi] = d + v.se;
                pq.push({-val[v.fi], v.fi});
            }
        }
    }

    DSU d(n);
    sort(edges+1, edges+1+m, [&](pair<int, int> &x, pair<int, int> &y) {return min(val[x.fi], val[x.se]) > min(val[y.fi], val[y.se]);});
    for (int i = 1; i <= m; ++i) {
        if (d.unite(edges[i].fi, edges[i].se)) {
            adj2[edges[i].fi].pb(edges[i].se);
            adj2[edges[i].se].pb(edges[i].fi);
        }
    }
    dfs(1, 0);
    cin >> q;
    while (q--) {
        int u, v; cin >> u >> v;
        cout << lca(u, v) << '\n';
    }

    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...