Cod sursa(job #3353462)

Utilizator PBaulurcaBurca Paul PBaulurca Data 7 mai 2026 15:16:07
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda cerc-acs-02-05-26 Marime 2.78 kb
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

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

const int MAXN = 15005;
const int LOG = 15; 

int parent[MAXN], rk[MAXN];

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

void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
        if (rk[a] < rk[b])
            swap(a, b);
        parent[b] = a;
        if (rk[a] == rk[b])
            rk[a]++;
    }
}

vector<pair<int, int>> adj[MAXN];

int depth[MAXN];
int up[MAXN][LOG];
int max_w[MAXN][LOG]; 
bool visited[MAXN];

void dfs(int u, int p, int edge_weight, int d) {
    visited[u] = true;
    depth[u] = d;
    up[u][0] = p;
    max_w[u][0] = edge_weight;

    for (int i = 1; i < LOG; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
        max_w[u][i] = max(max_w[u][i - 1], max_w[up[u][i - 1]][i - 1]);
    }

    for (auto edge : adj[u]) {
        int v = edge.first;
        int w = edge.second;
        if (v != p) {
            dfs(v, u, w, d + 1);
        }
    }
}

int query(int u, int v) {
    int ans = 0;
    
    if (depth[u] < depth[v])
        swap(u, v);

    int diff = depth[u] - depth[v];
    for (int i = 0; i < LOG; i++) {
        if ((diff >> i) & 1) {
            ans = max(ans, max_w[u][i]);
            u = up[u][i];
        }
    }

    if (u == v)
        return ans;

    for (int i = LOG - 1; i >= 0; i--) {
        if (up[u][i] != up[v][i]) {
            ans = max(ans, max_w[u][i]);
            ans = max(ans, max_w[v][i]);
            u = up[u][i];
            v = up[v][i];
        }
    }

    ans = max(ans, max_w[u][0]);
    ans = max(ans, max_w[v][0]);

    return ans;
}

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

    if (freopen("radiatie.in", "r", stdin)) {
        freopen("radiatie.out", "w", stdout);
    }

    int N, M, K;
    cin >> N >> M >> K;

    vector<Edge> edges(M);
    for (int i = 0; i < M; ++i) {
        cin >> edges[i].u >> edges[i].v >> edges[i].w;
    }

    for (int i = 1; i <= N; ++i) {
        parent[i] = i;
        rk[i] = 0;
    }

    sort(edges.begin(), edges.end());

    int cnt = 0;
    for (const auto& edge : edges) {
        if (find_set(edge.u) != find_set(edge.v)) {
            union_sets(edge.u, edge.v);
            adj[edge.u].push_back({edge.v, edge.w});
            adj[edge.v].push_back({edge.u, edge.w});
            cnt++;
            if (cnt == N - 1) break;
        }
    }

    for (int i = 1; i <= N; ++i) {
        if (!visited[i]) {
            dfs(i, i, 0, 0); 
        }
    }

    for (int i = 0; i < K; ++i) {
        int x, y;
        cin >> x >> y;
        cout << query(x, y) << "\n";
    }

    return 0;
}