Cod sursa(job #1582380)

Utilizator vnedelcuVictor Andrei Nedelcu vnedelcu Data 27 ianuarie 2016 21:16:58
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.09 kb
#include <stdio.h>
#include <algorithm>

const int nmax=15001;
const int mmax=30001;
const int NIL=-1;

struct muchie
{
    int n1,n2,cost;
};

muchie mv[mmax];

struct element
{
    int nod,cost,next;
};

element buff[2*(nmax-1)];
int head[nmax];

bool cmp(muchie a, muchie b)
{
    return a.cost < b.cost;
}

int parent[nmax];
int nrnoduri[nmax];

int findparent(int x)
{
    if (parent[x] == x)
        return x;
    return findparent(parent[x]);
}

void unire(int a, int b)
{
    if (nrnoduri[a] > nrnoduri[b])
    {
        parent[b]=a;
        nrnoduri[a]+=nrnoduri[b];
    }
    else
    {
        parent[a]=b;
        nrnoduri[b]+=nrnoduri[a];
    }
}

void push(int n1, int n2, int cost, int pos)
{
    buff[pos].nod=n2;
    buff[pos].cost=cost;
    buff[pos].next=head[n1];
    head[n1]=pos;
}

struct element2
{
    int nod,cost;
};

element2 str[14][nmax];///str [i][j]=stramosul cu 2^i nivele mai sus al lui j

int ap[nmax];
int lvl[nmax];

void dfs(int nod, int lev)
{
    int i;

    ap[nod]=1;
    lvl[nod]=lev;
    i=head[nod];
    while (i != NIL)
    {
        if (!ap[buff[i].nod])
        {
            str[0][buff[i].nod].nod=nod;///stramosul direc al nodului buff[i].nod este nod
            str[0][buff[i].nod].cost=buff[i].cost;
            dfs(buff[i].nod,lev+1);
        }
        i=buff[i].next;
    }
}

int lg[nmax];

void precalc (int n)
{
    int i;

    lg[1]=0;
    for (i=2; i<=n; i++)
        lg[i]=lg[i/2]+1;
}

int lca(int x, int y)
{
    int log1,log2,i,aux;

    log1=lg[lvl[x]];
    log2=lg[lvl[y]];

             if (lvl[x] < lvl[y])
    {
        aux=x;
        x=y;
        y=aux;
    }

    aux=-1;
    for (i=log1; i>=0; i--)
        if (lvl[x] - (1 << i) >= lvl[y])
        {
            if (str[i][x].cost > aux)
                aux=str[i][x].cost;
            x=str[i][x].nod;
        }

    if (x == y)
        return aux;

    for (i=log2; i>=0; i--)
        if ((str[i][x].nod != str[i][y].nod) && (str[i][x].nod != 1))
        {
            if (str[i][x].cost > aux)
                aux=str[i][x].cost;
            if (str[i][y].cost > aux)
                aux=str[i][y].cost;
                x=str[i][x].nod;
                y=str[i][y].nod;
        }

    if (str[0][x].cost > aux)
        aux=str[0][x].cost;
     if (str[0][y].cost > aux)
        aux=str[0][y].cost;

    return aux;
}

int main()
{
    FILE *fin,*fout;
    int n,m,k,a,b,i,j,nrcconex,pos,x,y;

    fin=fopen("radiatie.in","r");
    fscanf(fin,"%d%d%d",&n,&m,&k);

    for (i=1; i<=n; i++)
        fscanf(fin,"%d%d%d",&mv[i].n1,&mv[i].n2,&mv[i].cost);


    ///incepe Kruskal
    std::sort(mv+1,mv+m+1,cmp);///sortare muchii

    for (i=1; i<=n; i++)
    {
        parent[i]=i;///initializare parinti noduri arbore
        nrnoduri[i]=1;///initializez numarul de noduri pe care il are fiecare arbore
        head[i]=-1;
    }

    nrcconex=n;

    pos=1;///poz in vectorul de muchii
    j=1;///poz in buff
    while (nrcconex != 1)
    {
        a=findparent(mv[pos].n1);
        b=findparent(mv[pos].n2);
        if (a != b)
        {
            unire(a,b);
            push(mv[pos].n1,mv[pos].n2,mv[pos].cost,j);
            j++;
            push(mv[pos].n2,mv[pos].n1,mv[pos].cost,j);
            j++;
            nrcconex--;
        }
        pos++;
    }
    ///se termina Kruskal

    dfs(1,1);///fac un dfs ca sa aflu nivelul fiecarui nod in arbore, considerand ca nodul 1 este radacina

    ///incepe Stramosi
    for (i=1; (1 << i) <= n; i++)
        for (j=1; j <= n; j++)
        {
            str[i][j].nod=str[i-1][str[i-1][j].nod].nod;
            str[i][j].cost=str[i-1][str[i-1][j].nod].cost;
            if (str[i-1][j].cost > str[i][j].cost)
                str[i][j].cost=str[i-1][j].cost;
        }
    ///se termina Stramosi

    precalc(n);

    fout=fopen("radiatie.out","w");
    for (i=1; i <= k; i++)
    {
        fscanf(fin,"%d%d",&x,&y);
        fprintf(fout,"%d\n",lca(x,y));
    }
    fclose(fin);
    fclose(fout);
}