Cod sursa(job #2169664)

Utilizator Constantin.Dragancea Constantin Constantin. Data 14 martie 2018 16:31:26
Problema Radiatie Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <bits/stdc++.h>
using namespace std;

struct edge{
    int a, b, c;
} M[30010];

int n, m, k, q, lvl[15010], p[15010], dp[15][15010], c[15][15010];
vector <pair<int,int> > v[15010];

int pp;
#define dim 100000
char buff[dim];

void read(int &nr){
    nr = 0;
    while (buff[pp] < '0' || buff[pp] > '9')
        if (++pp == dim) fread(buff, 1, dim, stdin), pp = 0;
    while (buff[pp]>='0' && buff[pp]<='9'){
        nr = nr*10 + buff[pp] - '0';
        if (++pp == dim) fread(buff, 1, dim, stdin), pp = 0;
    }
}

bool cmp(edge a, edge b){
    return a.c < b.c;
}

int find(int i){
    if (i == p[i]) return i;
    p[i] = find(p[i]);
    return p[i];
}

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

int get(int nod, int dist){
    if (!dist) return 0;
    int put = 0;
    while ((1<<(put+1)) <= dist) put++;
    return max(c[put][nod], get(dp[put] [nod], dist - (1<<put)));
}

int get_ancestor(int nod, int dist){
    if (!dist) return nod;
    int put = 0;
    while ( (1<<(put+1)) <= dist) put++;
    return get_ancestor(dp[put][nod], dist - (1<<put));
}

void build(){
    //al 2^j-lea stramosi
    for (int i=1; (1<<i) <= n; i++){
        for (int 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]]);
        }
    }
    //costul maxim in ultimii 2^j-lea stramosi ai lui i
}

int main(){
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    read(n); read(m); read(q);
    for (int i=1; i<=m; i++){
        int x, y, z;
        read(x); read(y); read(z);
        M[i] = {x, y, z};
    }
    sort(M+1, M+1+m, cmp);
    for (int i=1; i<=n; i++) p[i] = i;
    for (int i=1; i<=m && k < n - 1; i++){
        int a = find(M[i].a), b = find(M[i].b);
        if (a != b){
            p[a] = b;
            v[M[i].a].push_back({M[i].b, M[i].c});
            v[M[i].b].push_back({M[i].a, M[i].c});
            k++;
        }
    }
    lvl[1] = 1;
    dfs(1);
    build();
    for (int i=1; i<=q; i++){
        int x, y, ans = 0;
        read(x); read(y);
        if (lvl[x] < lvl[y]) swap(x, y);
        ans = get(x, lvl[x] - lvl[y]);
        x = get_ancestor(x, lvl[x] - lvl[y]);
        while (x != y){
            int put = 0;
            while (dp[put][x] != dp[put][y]){
                ans = max({ans, c[put][x], c[put][y]});
                put++;
            }
            x = dp[put-1][x]; y = dp[put-1][y];
        }
        cout << ans << "\n";
    }
    return 0;
}