Cod sursa(job #2962881)

Utilizator velciu_ilincavelciu ilinca velciu_ilinca Data 9 ianuarie 2023 18:11:33
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.23 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
ifstream in("radiatie.in");
ofstream out("radiatie.out");

int n,m,k;
int rang[30001];
int tata[30001];
int nivel[15001],level=1;
int stramos[55][15005];
int maxim[55][15005];
int log2n;
int muchiemax=0;

struct elem
{
    int st;
    int dr;
    int price;
};
struct vecini
{
    int child;
    int pret;
};
elem v[30005];
vector<elem>rez;
vector<vecini>g[15005];

bool cmp(elem x,elem y)
{
    return x.price<y.price;
}

void initialize_for_apm()
{
    for(int i=1;i<=n;i++)
    {
        tata[i]=i;
        rang[i]=1;
    }
}

int find1(int x)
{
    if (x == tata[x])
        return x;
    return tata[x] = find1(tata[x]);
}

void union1(int reprez1,int reprez2)
{
    if(rang[reprez1]==rang[reprez2])
    {
        tata[reprez2]=reprez1;
        rang[reprez1]++;
    }
    else if(rang[reprez1]<rang[reprez2])
    {
        tata[reprez1]=reprez2;
    }
    else if(rang[reprez1]>rang[reprez2])
    {
        tata[reprez2]=reprez1;
    }
}

void dfs(int node,int level)
{
    nivel[node]=level;
    level++;
    for(int i=0;i<g[node].size();i++)
        if(nivel[g[node][i].child]==0)
        {
            stramos[0][g[node][i].child]=node;
            maxim[0][g[node][i].child]=g[node][i].pret;
            dfs(g[node][i].child,level);
        }
}

void dp_stramosi()
{
    for(int i=1;i<=log2n;i++)
        for(int j=1;j<=n;j++)
        {
            stramos[i][j]=stramos[i-1][stramos[i-1][j]];
            maxim[i][j]=max(maxim[i-1][j],maxim[i-1][stramos[i-1][j]]);
        }
}

int equalize(int up,int node)
{
    for(int i=log2n;i>=0;i--)
        if(nivel[node]-1>=(1<<i) && up>=(1<<i) && stramos[i][node]!=0)
        {
            muchiemax=max(muchiemax,maxim[i][node]);
            node=stramos[i][node];
            up=up-(1<<i);
        }
    return node;
}

int max3(int a,int b,int c)
{
    int rez=a;
    if(rez<b)
        rez=b;
    if(rez<c)
        rez=c;
    return rez;
}

void lca(int x,int y)
{
    if(x==y)
        out<<muchiemax<<'\n';
    else
    {
        for(int i=log2n;i>=0;i--)
            if(stramos[i][x]!=stramos[i][y])
            {
                muchiemax=max3(muchiemax,maxim[i][x],maxim[i][y]);
                x=stramos[i][x];
                y=stramos[i][y];
            }
        muchiemax=max3(muchiemax,maxim[0][x],maxim[0][y]);
        out<<muchiemax<<'\n';
        //out<<stramos[0][x]<<'\n';
    }
}

int main()
{
    in>>n>>m>>k;
    log2n=log2(n);///log pt stramosi

    initialize_for_apm();///rang si tata

    for(int i=1;i<=m;i++)
        in>>v[i].st>>v[i].dr>>v[i].price;

    sort(v+1,v+m+1,cmp);

    for(int i=1;i<=m;i++)
    {
        if(find1(v[i].st)!=find1(v[i].dr))
        {
            int nr1=find1(v[i].st);
            int nr2=find1(v[i].dr);
            union1(nr1,nr2);
            elem newfound;
            newfound.st=v[i].st;
            newfound.dr=v[i].dr;
            newfound.price=v[i].price;
            rez.push_back(newfound);
        }
    }

    for(int i=0;i<rez.size();i++)
    {
        //cerr << rez[i].st << ' ' << rez[i].dr << '\n';
        vecini newelem;
        newelem.child=rez[i].dr;
        newelem.pret=rez[i].price;

        g[rez[i].st].push_back(newelem);

        newelem.child=rez[i].st;
        g[rez[i].dr].push_back(newelem);
        //stramos[0][rez[i].dr]=rez[i].st;
        //maxim[0][rez[i].dr]=rez[i].price;
    }

    int reprezfinal;
    reprezfinal=find1(1);
    dfs(reprezfinal,1);

    ///construim dinamica
    dp_stramosi();

    for(int i=1;i<=k;i++)
    {
        muchiemax=0;
        int x,y;
        in>>x>>y;
        int copil;
        if(nivel[x]!=nivel[y])
        {
            int up=0;
            if(nivel[x]>nivel[y])
            {
                up=nivel[x]-nivel[y];
                copil=equalize(up,x);
                lca(copil,y);
            }
            else
            {
                up=nivel[y]-nivel[x];
                copil=equalize(up,y);
                lca(copil,x);
            }
        }
        else
            lca(x,y);
    }
    return 0;
}