Cod sursa(job #3240788)

Utilizator AlexPlesescuAlexPlesescu AlexPlesescu Data 20 august 2024 20:48:27
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <bits/stdc++.h>

using namespace std;
#define pb push_back
#define sz(x) (int)(x.size())
const int N = 15005, len = 17, Q = 1005, mod = 1e9 + 7;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

int n, m, k, parent[N], sz[N], up[N][len + 1], rmq[N][len + 1];
int out[N], in[N], timer;
vector<pair<int, pair<int, int>>> edges;
vector<pair<int, int>> g[N];

int find_root(int x) {
    if (parent[x] == x)
        return x;
    return parent[x] = find_root(parent[x]);
}

void unite(int x, int y) {
    int a = find_root(x);
    int b = find_root(y);
    if (a != b) {
        if (sz[a] < sz[b]) {
            sz[b] += sz[a];
            parent[a] = b;
        } else {
            sz[a] += sz[b];
            parent[b] = a;
        }
    }
}

void compute(int u, int p = 0, int prev_weight = 0) {
    in[u] = ++timer;
    up[u][0] = p;
    rmq[u][0] = prev_weight;
    for (int i = 1; i <= len; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
        rmq[u][i] = max(rmq[u][i - 1], rmq[up[u][i - 1]][i - 1]);
    }
    for (auto e: g[u]) {
        if (e.first != p) {
            compute(e.first, u, e.second);
        }
    }
    out[u] = ++timer;
}

inline bool is_ancestor(int u, int v) {
    return in[u] <= in[v] && out[u] >= out[v];
}

int query(int u, int v) {
    int max_weight = 0;
    if (is_ancestor(u, v))
        return 0;
    for (int i = len; i >= 0; i--) {
        if (!is_ancestor(up[u][i], v)) {
            max_weight = max(max_weight, rmq[u][i]);
            u = up[u][i];
        }
    }
    max_weight = max(max_weight, rmq[u][0]);
    return max_weight;
}

int main() {
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    int t = 1;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
        parent[i] = i, sz[i] = 1;
    for (int i = 1; i <= m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        edges.pb({c, {a, b}});
    }
    sort(edges.begin(), edges.end());
    for (int i = 0; i < m; i++) {
        int A = find_root(edges[i].second.first);
        int B = find_root(edges[i].second.second);
        if (A != B) {
            g[edges[i].second.first].pb({edges[i].second.second, edges[i].first});
            g[edges[i].second.second].pb({edges[i].second.first, edges[i].first});
            unite(A, B);
        }
    }
    compute(1);
    while (k--) {
        int x, y;
        cin >> x >> y;
        cout << max(query(x, y), query(y, x)) << '\n';
    }
}