Cod sursa(job #2447292)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 12 august 2019 19:20:12
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
#define DIMN 15010
#define DIMM 30010
using namespace std;

ifstream fin ("radiatie.in");
ofstream fout ("radiatie.out");
struct muchie{
    int x,y,cost;
};
muchie mch[DIMM];
vector < pair<int,int> > L[DIMN];
int E[3*DIMN],niv[DIMN],t[DIMN],first[DIMN],p[3*DIMN];
pair <int,int> d[20][3*DIMN];
int stramos[20][3*DIMN],cost[20][3*DIMN];
int n,m,q,x,y,c,i,j,k;
inline int cmp (muchie a, muchie b){
    return a.cost < b.cost;
}
inline int get_rad (int x){
    int y = x;
    while (t[x] > 0)
        x = t[x];
    /*while (t[y] > 0){
        int aux = y;
        t[y] = x;
        y = aux;
    }*/
    return x;
}
void dfs (int nod, int tata){
    E[++k] = nod;
    first[nod] = k;
    niv[nod] = 1+niv[tata];
    for (int i=0;i<L[nod].size();i++){
        int vecin = L[nod][i].first;
        if (vecin != tata){
            dfs (vecin,nod);
            E[++k] = nod;
            cost[0][vecin] = L[nod][i].second;
            stramos[0][vecin] = nod; /// al 2^i lea stramos al lui nod
        }}}
inline int get_lca (int x, int y){
    int pozx = first[x], pozy = first[y];
    if (pozx > pozy)
        swap (pozx,pozy);
    int nr = p[pozy-pozx+1];
    pair <int,int> sol = min (d[nr][pozx],d[nr][pozy-(1<<nr)+1]);
    return E[sol.second];
}
int solve (int x, int y){
    int lca = get_lca (x,y);
    int nr = niv[x] - niv[lca];
    int maxi = 0;
    /// ma plimb pe lant din puteri in puteri de 2 si calculez maximul
    for (int i=20;i>=0;i--){
        if ( (1<<i) <= nr ){
            maxi = max (maxi,cost[i][x]);
            nr -= (1<<i);
            x = stramos[i][x];
        }}
    /// fac acelasi lucru si pentru y
    nr = niv[y] - niv[lca];
    for (int i=20;i>=0;i--){
        if ((1<<i) <= nr){
            maxi = max (maxi,cost[i][y]);
            nr -= (1<<i);
            y = stramos[i][y];
        }}
    return maxi;
}
int main (){

    fin>>n>>m>>q;
    for (i=1;i<=m;i++){
        fin>>x>>y>>c;
        mch[i] = {x,y,c};
    }
    /// cosntruiesc apm ul
    sort (mch+1,mch+m+1,cmp);
    memset (t,-1,sizeof t);

    for (i=1;i<=m;i++){
        int rx = get_rad(mch[i].x);
        int ry = get_rad(mch[i].y);
        if (rx == ry)
            continue;
        L[mch[i].x].push_back(make_pair(mch[i].y,mch[i].cost));
        L[mch[i].y].push_back(make_pair(mch[i].x,mch[i].cost));
        if (t[rx] < t[ry]){
            t[rx] += t[ry];
            t[ry] = rx;
        } else {
            t[ry] += t[rx];
            t[rx] = ry;
        }}

    dfs (1,0);

    for (i=1;i<=k;i++)
        d[0][i] = make_pair(niv[E[i]],i);
    for (i=2;i<=k;i++)
        p[i] = p[i/2]+1;

    /// tin maximele pe lanturi putere de 2
    for (i=1;(1<<i)<=k;i++)
        for (j=1;j<=k;j++){
            stramos[i][j] = stramos[i-1][stramos[i-1][j]];
            cost[i][j] = max (cost[i-1][j],cost[i-1][stramos[i-1][j]]);
            d[i][j] = d[i-1][j];
            if (j+(1<<(i-1)) <= k && d[i-1][j+(1<<(i-1))].first < d[i][j].first)
                d[i][j] = d[i-1][j+(1<<(i-1))];
        }

    for (;q--;){
        fin>>x>>y;
        fout<<solve(x,y)<<"\n";
    }

    return 0;
}