Cod sursa(job #3300575)

Utilizator iulia_morariuIuli Morariu iulia_morariu Data 17 iunie 2025 13:02:40
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.99 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <stack>
#include <cmath>
// #include <bits/stdc++.h>
#define in  fin
#define out fout
#define mkp make_pair

using namespace std;

ifstream fin("radiatie.in");
ofstream fout("radiatie.out");

int f[15001], s[15001];

int find_father(int x){
    if(x == f[x]) return x;
    f[x] = find_father(f[x]);
    return f[x];
}

void merge(int a, int b){
    int f1 = find_father(a);
    int f2 = find_father(b);

    if(f1 == f2) return;

    if(s[f1] > s[f2]){
        s[f1] += s[f2];
        f[f2] = f1;
    }else{
        s[f2] += s[f1];
        f[f1] = f2;
    }
}

int care_copil[15001];
vector< pair<int, int> > g[15001];
vector<int> l; // l[i] = capul lantului i
int n;

struct nod{
    int val, lant, nivel, dad, idx, sch;
};
nod v[15001];

void build_lanturi(int node){
    // cerr << "node = " << node << '\n';
    if(g[node].size() == 1 && g[node][0].first == v[node].dad){ // e leaf.
        l.push_back(node);
        v[node].lant = l.size() - 1;
        v[node].sch = 0;
        return;
    }

    int maxi = -1, cntmx = 0, care = 0;
    for(const pair<int, int> &x : g[node]){
        if(x.first == v[node].dad) continue;
        v[x.first].dad = node;
        v[x.first].val = x.second;
        v[x.first].nivel = v[node].nivel + 1;
        build_lanturi(x.first);

        if(v[x.first].sch > maxi){
            maxi = v[x.first].sch;
            cntmx = 1;
            care = x.first;
        }else if(v[x.first].sch == maxi) cntmx++;
    }

    care_copil[node] = care;
    v[node].lant = v[care].lant;
    l[ v[node].lant ] = node;
    if(cntmx == 1) v[node].sch = maxi;
    else v[node].sch = maxi + 1;
}

bool cmp(const int &a, const int &b){
    if(v[a].lant != v[b].lant) return v[a].lant < v[b].lant;
    else return v[a].nivel < v[b].nivel;
}

vector<int> srt;
void reindexare(){
    for(int i = 1; i <= n; i++) srt.push_back(i);
    sort(srt.begin(), srt.end(), cmp);
    for(int i = 0; i < n; i++){
        v[ srt[i] ].idx = i + 1;
    }
}

// ainttt
int aint[4 * 15001];

void build(int l, int r, int p){
    if(l == r){
        aint[p] = v[ srt[l - 1] ].val;
        return;
    }

    int m = (l + r) / 2;
    build(l, m, p * 2);
    build(m + 1, r, p * 2 + 1);
}

void update(int l, int r, int p, int poz, int val){
    if(l == r){
        aint[p] = val;
        return;
    }

    int m = (l + r) / 2;
    if(poz <= m) update( l, m, p * 2, poz, val );
    else update( m + 1, r, p * 2 + 1, poz, val );


    aint[p] = max(aint[p * 2], aint[p * 2 + 1]);
}

int query(int l, int r, int p, int l1, int r1){
    if(l1 <= l && r <= r1) return aint[p];

    int sol = 0;
    int m = (l + r) / 2;
    if(l1 <= m) sol = max(sol, query(l, m, p * 2, l1, r1));
    if(m <  r1) sol = max(sol, query(m + 1, r, p * 2 + 1, l1, r1));

    return sol;
}

int query_for_real(int a, int b){
    // pas 1 = le aducem la acelasi lant
    int sol = 0;
    while(v[a].lant != v[b].lant){
        // cerr << "a = " << a << " b = " << b << '\n';
        // cerr << "nivel = " << v[a].nivel << " " << v[b].nivel << '\n';
        int capa = l[ v[a].lant ];
        int capb = l[ v[b].lant ];

        if(v[capa].nivel > v[capb].nivel){ // il urc pe a
            sol = max(sol, query(1, n, 1, v[capa].idx, v[a].idx));
            a = v[capa].dad;
        }else{
            sol = max(sol, query(1, n, 1, v[capb].idx, v[b].idx));
            b = v[capb].dad;
        }
    }
    if(a == b) return sol;

    if(v[a].nivel > v[b].nivel){
        b = care_copil[b];
        sol = max(sol, query(1, n, 1, v[b].idx, v[a].idx));
    }else{
        a = care_copil[a];
        sol = max(sol, query(1, n, 1, v[a].idx, v[b].idx));
    }
    return sol;
}

signed main(){
    ios_base::sync_with_stdio(false);
    in.tie(NULL);

    int m, q; in >> n >> m >> q;
    vector< pair< int, pair<int, int> > > mch(m);
    for(int i = 0; i < m; i++){
        in >> mch[i].second.first >> mch[i].second.second >> mch[i].first;
        // mch[i].second.first--; mch[i].second.second--;
    }

    for(int i = 0; i <= n; i++){
        f[i] = i;
        s[i] = 1;
    }

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

    for(int i = 0; i < m; i++){
        int a = mch[i].second.first, b = mch[i].second.second, c = mch[i].first;
        if(find_father(a) != find_father( b )){
            g[a].push_back( mkp(b, c) );
            g[b].push_back( mkp(a, c) );
            merge(a, b);
        }
    }

    // cout << "APM : ";
    // for(int i = 1; i <= n; i++){
    //     for(int j = 0; j < g[i].size(); j++){
    //     cout << "( " << i << " , " << g[i][j].first << " , " << g[i][j].second << " ) ";
    //     }
    // }
    // cout << '\n';

    build_lanturi(1);
    reindexare();
    build(1, n, 1);

    // cout << "l : ";
    // for(const int &x : l) cout << x << " ";
    // cout << '\n';

    // cout << "idx : ";
    // for(int i = 1; i <= n; i++) cout << v[i].idx << " ";
    // cout << '\n';

    for(int i = 0; i < q; i++){
        int a, b; in >> a >> b;
        out << query_for_real(a, b) << '\n';
    }

    return 0;
}