Submission #1346756

#TimeUsernameProblemLanguageResultExecution timeMemory
1346756huhuhihiEvacuation plan (IZhO18_plan)C++20
100 / 100
266 ms68152 KiB
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstdio>

using namespace std;

typedef long long ll;
const ll INF = 1e18;
const int MAXN = 100005;
const int LOG = 18;

struct Edge {
    int u, v;
    ll w;
};

struct GraphEdge {
    int to;
    ll w;
};

int n, m, k, q;
vector<GraphEdge> adj[MAXN], tree[MAXN];
ll dist[MAXN];
int up[MAXN][LOG];
ll me[MAXN][LOG];
int depth[MAXN];
int parent[MAXN];

int find_set(int v) {
    if (v == parent[v]) return v;
    return parent[v] = find_set(parent[v]);
}

bool union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
        parent[b] = a;
        return true;
    }
    return false;
}

bool cmp(const Edge& a, const Edge& b) {
    return a.w > b.w;
}

void dfs(int u, int p, int d, ll w) {
    depth[u] = d;
    up[u][0] = p;
    me[u][0] = w;
    for (int i = 1; i < LOG; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
        me[u][i] = min(me[u][i - 1], me[up[u][i - 1]][i - 1]);
    }
    for (size_t i = 0; i < tree[u].size(); i++) {
        if (tree[u][i].to != p) {
            dfs(tree[u][i].to, u, d + 1, tree[u][i].w);
        }
    }
}

ll get_min_path(int u, int v) {
    if (u == v) return dist[u];
    if (depth[u] < depth[v]) swap(u, v);
    ll res = INF;
    for (int i = LOG - 1; i >= 0; i--) {
        if (depth[u] - (1 << i) >= depth[v]) {
            res = min(res, me[u][i]);
            u = up[u][i];
        }
    }
    if (u == v) return res;
    for (int i = LOG - 1; i >= 0; i--) {
        if (up[u][i] != up[v][i]) {
            res = min(res, min(me[u][i], me[v][i]));
            u = up[u][i];
            v = up[v][i];
        }
    }
    return min(res, min(me[u][0], me[v][0]));
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

  

    if (!(cin >> n >> m)) return 0;
    vector<Edge> all_edges;
    for (int i = 0; i < m; i++) {
        int u, v; ll l;
        cin >> u >> v >> l;
        adj[u].push_back({v, l});
        adj[v].push_back({u, l});
        all_edges.push_back({u, v, 0});
    }

    // Dijkstra da nguon tu K phong co coi
    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
    for (int i = 1; i <= n; i++) dist[i] = INF;
    cin >> k;
    for (int i = 0; i < k; i++) {
        int x; cin >> x;
        dist[x] = 0;
        pq.push({0, x});
    }

    while (!pq.empty()) {
        ll d = pq.top().first;
        int u = pq.top().second;
        pq.pop();
        if (d > dist[u]) continue;
        for (size_t i = 0; i < adj[u].size(); i++) {
            int v = adj[u][i].to;
            ll w = adj[u][i].w;
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }

    // Xay dung Cay khung lon nhat (Maximum Spanning Tree)
    for (int i = 0; i < m; i++) {
        all_edges[i].w = min(dist[all_edges[i].u], dist[all_edges[i].v]);
    }
    sort(all_edges.begin(), all_edges.end(), cmp);

    for (int i = 1; i <= n; i++) parent[i] = i;
    for (int i = 0; i < m; i++) {
        if (union_sets(all_edges[i].u, all_edges[i].v)) {
            tree[all_edges[i].u].push_back({all_edges[i].v, all_edges[i].w});
            tree[all_edges[i].v].push_back({all_edges[i].u, all_edges[i].w});
        }
    }

    // Tien xu ly LCA
    for (int i = 1; i <= n; i++) {
        if (depth[i] == 0) dfs(i, i, 1, INF);
    }

    cin >> q;
    while (q--) {
        int s, t;
        cin >> s >> t;
        ll ans = get_min_path(s, t);
        // Do an toan thap nhat con phu thuoc vao diem dau va diem cuoi
        ans = min(ans, min(dist[s], dist[t]));
        cout << ans << "\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...