제출 #1324369

#제출 시각아이디문제언어결과실행 시간메모리
1324369sh_qaxxorov_571Evacuation plan (IZhO18_plan)C++20
100 / 100
363 ms45308 KiB
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

/**
 * IZHO 2018 - Evacuation Plan
 * Vaqt murakkabligi: O(M log M + Q log N)
 * Xotira murakkabligi: O(N log N + M)
 */

const int MAXN = 100005;
const int LOG = 20;
const int INF = 1e9 + 7;

struct Edge {
    int u, v, w;
    bool operator>(const Edge& other) const { return w > other.w; }
};

vector<pair<int, int>> adj[MAXN], mst_adj[MAXN];
int dist_npp[MAXN], parent[MAXN];
int up[MAXN][LOG], min_edge[MAXN][LOG], depth[MAXN];
int n, m, k, q;

// 1. DSU (Disjoint Set Union) MST qurish uchun
int find_set(int v) {
    if (v == parent[v]) return v;
    return parent[v] = find_set(parent[v]);
}

// 2. Multi-source Dijkstra: Har bir shahardan eng yaqin AESgacha masofani topish
void compute_npp_distances(const vector<int>& npps) {
    fill(dist_npp + 1, dist_npp + n + 1, INF);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    for (int g : npps) {
        dist_npp[g] = 0;
        pq.push({0, g});
    }

    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();

        if (d > dist_npp[u]) continue;

        for (auto& edge : adj[u]) {
            int v = edge.first;
            int w = edge.second;
            if (dist_npp[u] + w < dist_npp[v]) {
                dist_npp[v] = dist_npp[u] + w;
                pq.push({dist_npp[v], v});
            }
        }
    }
}

// 3. MST bo'ylab LCA uchun tayyorgarlik
void dfs_lca(int u, int p, int d, int w) {
    depth[u] = d;
    up[u][0] = p;
    min_edge[u][0] = w;
    for (int i = 1; i < LOG; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
        min_edge[u][i] = min(min_edge[u][i - 1], min_edge[up[u][i - 1]][i - 1]);
    }
    for (auto& edge : mst_adj[u]) {
        if (edge.first != p) dfs_lca(edge.first, u, d + 1, edge.second);
    }
}

// 4. So'rovga javob berish (Yo'ldagi eng kichik xavflilik darajasini topish)
int get_max_dangerousness(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    int res = INF;
    for (int i = LOG - 1; i >= 0; i--) {
        if (depth[u] - (1 << i) >= depth[v]) {
            res = min(res, min_edge[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(min_edge[u][i], min_edge[v][i]));
            u = up[u][i];
            v = up[v][i];
        }
    }
    return min(res, min(min_edge[u][0], min_edge[v][0]));
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    if (!(cin >> n >> m)) return 0; // [cite: 24]
    vector<Edge> all_edges;
    for (int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w; // [cite: 26]
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
        all_edges.push_back({u, v, w});
    }

    cin >> k; // [cite: 27]
    vector<int> npps(k);
    for (int i = 0; i < k; i++) cin >> npps[i]; // [cite: 28]

    compute_npp_distances(npps);

    // Har bir yo'lning "xavflilik vazni" - ikki uchidagi minimal AES masofasi
    for (auto& e : all_edges) {
        e.w = min(dist_npp[e.u], dist_npp[e.v]);
    }

    // Maksimal Spanning Tree (MST) qurish 
    sort(all_edges.begin(), all_edges.end(), [](Edge a, Edge b) {
        return a.w > b.w;
    });

    for (int i = 1; i <= n; i++) parent[i] = i;
    for (auto& e : all_edges) {
        if (find_set(e.u) != find_set(e.v)) {
            parent[find_set(e.u)] = find_set(e.v);
            mst_adj[e.u].push_back({e.v, e.w});
            mst_adj[e.v].push_back({e.u, e.w});
        }
    }

    dfs_lca(1, 1, 0, INF);

    cin >> q; // [cite: 29]
    while (q--) {
        int s, t;
        cin >> s >> t; // [cite: 30]
        cout << get_max_dangerousness(s, t) << "\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...