Cod sursa(job #2711877)

Utilizator bluestorm57Vasile T bluestorm57 Data 24 februarie 2021 20:05:59
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.61 kb
/*
    Very hard!
    Don't try home
*/



#include <bits/stdc++.h>

using namespace std;

ifstream f("radiatie.in");
ofstream g("radiatie.out");

inline void Boost(){
    ios::sync_with_stdio(false);
    f.tie(NULL);g.tie(NULL);
}

const int NMAX = 15005;
const int LMAX = 16;
int sz[NMAX],link[NMAX],dist[NMAX],dp[LMAX][NMAX],c[LMAX][NMAX],n;
vector < tuple < int,int,int> > edges;
vector < pair < int, int> > v[NMAX];

int find(int x){
    while(x != link[x])
        x = link[x];
    return x;
}

void unite(int x, int y){
    x = find(x);
    y = find(y);
    if(sz[y] > sz[x])
        swap(x,y);
    sz[x] += sz[y];
    link[y] = x;
}

void dfs(int nod){
    for(auto it: v[nod]){
        if(!dist[it.first]){
            dist[it.first] = dist[nod] + 1;
            dfs(it.first);
            dp[0][it.first] = nod;
            c[0][it.first] = it.second;
        }
    }
}

void buildDP(){
    int i,j;
    for(i = 1 ; (1 << i) <= n ; i++)
        for(j = 1 ; j <= n ; j++){
            dp[i][j] = dp[i - 1][dp[i - 1][j]];
            c[i][j] = max(c[i - 1][j], c[i - 1][dp[i - 1][j]]);
        }
}

int query(int x, int y){
    if(dist[x] < dist[y])
        swap(x,y);
    int L1 = 1;
    int L2 = 1;

    while ( (1<<L1) < dist[x])
        L1++;

    while ( (1<<L2) < dist[y])
        L2++;

    int maxim = 0,i,j;
    for(i = L1 ; i >= 0 ; i--)
        if(dist[x] - (1 << i) >= dist[y]){
            maxim = max(maxim, c[i][x]);
            x = dp[i][x];
        }

    if(x == y)
        return maxim;

    for(i = L2 ; i >= 0 ; i--)
        if(dist[x] - (1 << i) >= 0 && dp[i][x] != dp[i][y] ){
            maxim = max(maxim, max(c[i][x], c[i][y]));
            x = dp[i][x];
            y = dp[i][y];
        }

    maxim = max(maxim, max(c[0][x], c[0][y]));
    return maxim;
}

int main(){
    Boost();
    int i,m,q,j;
    f >> n >> m >> q;
    for(i = 1 ; i <= n ; i++){
        link[i] = i;
        sz[i] = 1;
    }
    for(i = 1 ; i <= m ; i++){
        int x,y,c;
        f >> x >> y >> c;
        edges.push_back(make_tuple(c,x,y));
    }
    sort(edges.begin(), edges.end());

    for(auto it : edges){
        int cost = get<0> (it);
        int x = get<1> (it);
        int y = get<2> (it);

        if(find(x) != find(y)){
            v[x].push_back(make_pair(y,cost));
            v[y].push_back(make_pair(x,cost));
            unite(x,y);
        }
    }

    dfs(1);
    buildDP();

    for(i = 1 ; i <= q ; i++){
        int x, y;
        f >> x >> y;
        g << query(x,y) << "\n";
    }

    return 0;
}