Cod sursa(job #2513358)

Utilizator MarianConstantinMarian Constantin MarianConstantin Data 22 decembrie 2019 22:27:15
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <bits/stdc++.h>
#define pb push_back

using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
const int MAXN = 15010, MAXL = 20;

struct Edge {
    int from, to, cost;
    bool operator<(const Edge& other) const {
        return cost < other.cost;
    }
}edges[2 * MAXN];
vector<pair<int, int> > graph[MAXN], mst[MAXN];
int n, m, k, ma, dep[MAXN], fat[MAXN], cost[MAXN], lev[MAXN], lg[MAXN], dp[MAXL][MAXN];

void initialize() {
    for (int i = 1; i <= n; ++i)
        fat[i] = i;
}

int findFather(int node) {
    if (node == fat[node])
        return node;
    int f = findFather(fat[node]);
    fat[node] = f;
    return f;
}

void reunite(int x, int y) {
    if (dep[x] > dep[y])
        fat[y] = x;
    else
        fat[x] = y;
    if (dep[x] == dep[y])
        ++dep[y];
}

void kruskal() {
    for (int i = 0; i < k; ++i) {
        int x = edges[i].from, y = edges[i].to, f1, f2;
        f1 = findFather(x);
        f2 = findFather(y);
        if (f1 != f2) {
            mst[y].pb({x, edges[i].cost});
            mst[x].pb({y, edges[i].cost});
            reunite(f1, f2);
        }
    }
}

void preprocess() {
    for (int k = 1; (1 << k) <= n; ++k)
        for (int i = 1; i <= n; ++i)
            dp[k][i] = dp[k - 1][dp[k - 1][i]];
    for (int i = 2; i <= n; ++i)
        lg[i] = lg[i >> 1] + 1;
}

void dfs(int node, int level, int father, int c) {
    lev[node] = level;
    dp[0][node] = father;
    cost[node] = c;
    for (const auto& it: mst[node])
        if (!lev[it.first] && it.first != 1)
            dfs(it.first, level + 1, node, it.second);
}

int lca(int x, int y) {
    if (lev[x] < lev[y])
        swap(x, y);
    int log1 = lg[lev[x]], log2 = lg[lev[y]];
    for (int k = log1; k >= 0; --k)
        if (lev[x] - (1 << k) >= lev[y])
            x = dp[k][x];
    if (x == y)
        return x;
    for (int k = log2; k >= 0; --k)
        if (dp[k][x] && dp[k][x] != dp[k][y])
            x = dp[k][x], y = dp[k][y];
    return dp[0][x];
}

void findMax(int node, int father) {
    if (node == father)
        return;
    ma = max(ma, cost[node]);
    findMax(dp[0][node], father);
}

int main() {
    int t;
    fin >> n >> m >> t;
    for (int i = 0; i < m; ++i) {
        int x, y, c;
        fin >> x >> y >> c;
        graph[x].pb({y, c});
        graph[y].pb({x, c});
        edges[k++] = {x, y, c};
    }
    initialize();
    sort(edges, edges + k);
    kruskal();
    dfs(1, 0, 0, 0);
    preprocess();
    for (int i = 0; i < t; ++i) {
        int x, y, anc;
        fin >> x >> y;
        anc = lca(x, y);
        ma = 0;
        ///findMax(x, anc);
        ///findMax(y, anc);
        fout << ma << '\n';
    }
    return 0;
}