Cod sursa(job #2656583)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 8 octombrie 2020 01:50:08
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.31 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

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

int tt[15001], rg[15001], lev[15001];
int ttt[14][15001], b[14][15001];

struct latura
{
    int a, b, c;
}v[30001];

struct nod
{
    int info, cost;
    nod * urm;
}*vecin[30001];
nod * prim[30001];

int comparare(latura x, latura y)
{
    return x.c<y.c;
}
int find(int x)
{
    int r, y=x;
    while(tt[y]!=y)
    {
        y=tt[y];
    }
    r=y;
    //aplic compresia drumurilor
    while(tt[x]!=x)
    {
        y=tt[x];
        tt[x]=r;
        x=y;
    }
    return r;
}
void unite(int x, int y, int nr, int cost)
{
    if(rg[x]<rg[y])
    {
        tt[x]=y;
        //il adaug pe v[i].a la fiii lui v[i].b
        nod * aux = new nod;
        aux->info=v[nr].a;
        aux->cost=cost;
        aux->urm=NULL;
        if(prim[ v[nr].b ]==NULL)
        {
            prim[ v[nr].b ]=aux;
            vecin[ v[nr].b ]=aux;
        }
        else
        {
            vecin[ v[nr].b ]->urm=aux;
            vecin[ v[nr].b ]=aux;
        }
    }
    else
    {
        tt[y]=x;
        //il adaug pe v[i].b la fiii lui v[i].a
        nod * aux = new nod;
        aux->info=v[nr].b;
        aux->cost=cost;
        aux->urm=NULL;
        if(prim[ v[nr].a ]==NULL)
        {
            prim[ v[nr].a ]=aux;
            vecin[ v[nr].a ]=aux;
        }
        else
        {
            vecin[ v[nr].a ]->urm=aux;
            vecin[ v[nr].a ]=aux;
        }
    }
    if(rg[x]==rg[y])
    {
        rg[x]++;
    }
}
void DFS(int x, int lvl)
{
    lev[x]=lvl;
    nod * t=prim[x];
    while(t!=NULL)
    {
        ttt[0][t->info]=x;
        b[0][t->info]=t->cost;
        DFS(t->info, lvl+1);
        t=t->urm;
    }
}
int lca (int x, int y)
{
    int i, log1, log2, originalx, originaly, rez;
    if(lev[x]<lev[y])
    {
        swap(x, y);
    }
    originalx=x;
    originaly=y;
    //calculez log2 x si log2 y;
    for(log1=1; (1<<log1)<x; log1++);
    for(log2=1; (1<<log2)<x; log2++);
    //il aduc pe x la nivelul lui y;
    rez=0;
    for(i=log1; i>=0; i--)
    {
        if(lev[x]-(1<<i) >= lev[y])
        {
            rez=max(rez, b[i][x]);
            x=ttt[i][x];
        }
    }
    if(x==y) return rez;

    for(i=log2; i>=0; i--)
    {
        if(ttt[i][x] && ttt[i][x]!=ttt[i][y])
        {
            rez=max(rez, b[i][x]);
            x=ttt[i][x];

            rez=max(rez, b[i][y]);
            y=ttt[i][y];
        }
    }
    return max(rez, b[0][x]);
}

int main()
{
    int n, m, nrc, k, i, j, logn;
    fin>>n>>m>>nrc;

    for(i=1; i<=m; i++)
    {
        fin>>v[i].a>>v[i].b>>v[i].c;
    }

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

    for(i=1; i<=n; i++)
    {
        tt[i]=i;
    }

    k=0;
    i=1;
    while(k<n-1)
    {
        int aux1=find(v[i].a);
        int aux2=find(v[i].b);
        if(aux1!=aux2)
        {
            //cout<<"Unesc "<<aux1<<" cu "<<aux2<<"\n";
            //cout<<"rg["<<aux1<<"]= "<<rg[aux1]<<"\nrg["<<aux2<<"]= "<<rg[aux2]<<"\n";
            k++;
            unite(aux1, aux2, i, v[i].c);
            //cout<<"rg["<<aux1<<"]= "<<rg[aux1]<<"\nrg["<<aux2<<"]= "<<rg[aux2]<<"\n\n";
        }
        i++;
    }
    //caut radacina, adica numarul cu rg maxim si aplic DFS ca sa marchez nivelele
    int max1=0, rad;
    for(i=1; i<=n; i++)
    {
        if(rg[i]>max1)
        {
            max1=rg[i];
            rad=i;
        }
    }
    DFS(rad, 0);
    //cout<<"rad= "<<rad<<"\n";
    /*for(i=1; i<=n; i++)
    {
        cout<<"lev["<<i<<"]= "<<lev[i]<<"\n";
    }cout<<"\n";*/

    //afisez pentru fiecare vecinii sai:
    /*for(i=1; i<=n; i++)
    {
        cout<<i<<": ";
        nod * t = prim[i];
        while(t!=NULL)
        {
            cout<<t->info<<' ';
            t=t->urm;
        }
        cout<<"\n";
    }
    cout<<"\n";*/

    for(logn=1; (1<<logn)<n; logn++);
    for(i=1; i<=logn; i++)
    {
        for(j=1; j<=n; j++)
        {
            ttt[i][j]=ttt[i-1][ ttt[i-1][j] ];
            b[i][j]=max(b[i-1][j], b[i-1][ ttt[i-1][j] ]);
        }
    }

    int x, y;
    for(i=1; i<=nrc; i++)
    {
        fin>>x>>y;
        fout<<lca(x, y)<<"\n";
    }
}