Cod sursa(job #3037963)

Utilizator begusMihnea begus Data 26 martie 2023 18:33:29
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <bits/stdc++.h>
using namespace std;

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

#define f first
#define sn second

const int NMAX=15001;
const int LOG=16;

vector<pair<int, int>> children[NMAX];
int n, m, k, lk[NMAX], sz[NMAX], up[NMAX][LOG], upmin[NMAX][LOG], depth[NMAX];

struct edge{
    int a, b, w;
} e[NMAX*2];

int cmp(const edge &a, const edge &b){
    return a.w<b.w;
}

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

void unite(int a, int b, int w){
    a = find(a);
    b = find(b);
    if (sz[a]<sz[b]) swap(a,b);
    sz[a]+=sz[b];
    children[a].push_back({b, w});
    lk[b]=a;
}

void buildTree(){
    for(int i=1; i<=m; i++){
        if(find(e[i].a)!=find(e[i].b)){
            unite(e[i].a, e[i].b, e[i].w);
        }
    }
}

void dfs(int s){
    for(auto u : children[s]){
        depth[u.f]=depth[s]+1;
        up[u.f][0]=s;
        upmin[u.f][0]=u.sn;
        for(int j=1; j<LOG; j++){
            up[u.f][j]=up[up[u.f][j-1]][j-1];
            upmin[u.f][j]=max(upmin[u.f][j-1], upmin[up[u.f][j-1]][j-1]);
        }
        dfs(u.f);
    }
}

int lca(int a, int b){
    if(a==b) return 0;
    int minrad=INT_MIN;
    if(depth[a]<depth[b]) swap(a, b);
    int d = depth[a]-depth[b];
    for(int j=LOG-1; j>=0; j--){
        if(d & (1<<j)){
            minrad=max(minrad, upmin[a][j]);
            a=up[a][j];
        }    
    }
    if(a==b) return minrad;
    for(int j=LOG-1; j>=0; j--){
        if(up[a][j]!=up[b][j]){
            minrad=max(max(upmin[a][j], upmin[b][j]), minrad);
            a=up[a][j];
            b=up[b][j];
        }
    }
    return max(max(upmin[a][0], upmin[b][0]), minrad);
}

int main(){
    fin >> n >> m >> k;
    for(int i=1; i<=n; i++){
        lk[i]=i;
        sz[i]=1;
    } 
    for(int i=1; i<=m; i++){
        fin >> e[i].a  >> e[i].b >> e[i].w;
    }
    sort(e+1, e+m+1, cmp);
    buildTree();
    for(int j=0; j<LOG; j++){
        up[1][j]=1;
        upmin[1][j]=INT_MIN;
    } 
    for(int i=1; i<=n; i++)
        if(lk[i]==i)
            dfs(i);

    while(k--){
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << '\n';
    }
}