Cod sursa(job #1546387)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 7 decembrie 2015 23:30:34
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include<fstream>
#include<vector>
#include<algorithm>

using namespace std;

ifstream f("radiatie.in");
ofstream g("radiatie.out");

struct Lat
{
    int a, b, c;
};

Lat V[30005];
int n, m, k, rad;
vector <int> G[15005];
int TT[20][15005], CC[20][15005], Log[20000], RG[15005], Level[15005], use[15005];

void citire()
{
    int i;

    f>>n>>m>>k;
    for(i=1; i<=m; i++)
        f>>V[i].a>>V[i].b>>V[i].c;

}

bool comp(Lat m, Lat n)
{
    return (m.c < n.c);
}

int stramos(int nod)
{
    while(TT[0][nod]){
        nod = TT[0][nod];
    }
    return nod;
}

int ance(int nod, int k)
{
    int red;
    while(k){
        red = Log[k];
        nod = TT[nod][red];
        k -= 1<<red;
    }
    return nod;
}

void unite(int x, int y, int c)
{
    if(RG[x] > RG[y]){
        TT[0][y] = x;
        CC[0][y] = c;
    }
    if(RG[y] > RG[x]){
        TT[0][x] = y;
        CC[0][x] = c;
    }
    if(RG[x] == RG[y]){
        TT[0][x] = y;
        CC[0][x] = c;
        RG[y]++;
    }
}

void DFSL(int nod)
{
    use[nod] = 1;
    int i, vecin;
    for(i=0; i<G[nod].size(); i++){
        vecin = G[nod][i];
        if(!use[nod]){
            Level[vecin] = Level[nod] + 1;
            DFSL(vecin);
        }
    }
}

void precalc()
{
    int alese = 0, i, j;

    sort(V + 1, V + m + 1, comp);

    for(i=2; i<=n; i++)
        Log[i] = Log[i/2] + 1;

    for(i=1; alese < n-1; i++){
        if(stramos(V[i].a) != stramos(V[i].b)){
            unite(V[i].a, V[i].b, V[i].c);
            alese++;
        }
    }

    for(i=1; i<n; i++){
        if(TT[0][i])
            G[TT[0][i]].push_back(i);
        else
            rad = i;
    }

    Level[rad] = 1;
    DFSL(rad);

    for(i=1; i<=Log[n]; i++)
        for(j=1; j<=n; j++){
            TT[i][j] = TT[i-1][TT[i-1][j]];
            CC[i][j] = max(CC[i-1][j], CC[i-1][TT[i-1][j]]);
        }
}

void LCA(int x, int y)
{
    int diff, maxi = 0, i;

    if(Level[x] < Level[y])
        swap(x,y);

    diff = Level[x] - Level[y];
    x = ance(x, diff);

    for(i = Log[Level[x]]; i > 0; i--)
        if(TT[i][x] != TT[i][y]){
            maxi = max(maxi, max(CC[i][x], CC[i][y]));
            x = TT[i][x];
            y = TT[i][y];
        }
    maxi = max(maxi, max(CC[0][x], CC[0][y]));

    g<<maxi<<"\n";
}

int main()
{
    int x, y;
    citire();
    precalc();
    for(int i=1; i<=k; i++){
        f>>x>>y;
        LCA(x, y);
    }
    return 0;
}