Cod sursa(job #864247)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 24 ianuarie 2013 20:07:35
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>
#include <algorithm>
#include <vector>

#define NMAX 15005
#define MMAX 30005
#define LMAX 14
#define f first
#define s second
#define pb push_back

using namespace std;

int N, M, K;
int dad[NMAX], cnt[NMAX], viz[NMAX], lvl[NMAX];
int TT[NMAX][LMAX], C[NMAX][LMAX];
pair<int, pair<int, int> > G[MMAX];
vector<int> V[NMAX];

int Find(int nod)
{
    int R = nod, X;
    while(nod != dad[nod])
        nod = dad[nod];
    while(R != nod)
    {
        X = dad[R];
        dad[R] = nod;
        R = X;
    }
    return nod;
}

void Merge(int A, int B)
{
    if(cnt[A] >= cnt[B]) dad[B] = A, cnt[A]++;
    else dad[A] = B, cnt[B]++;
}

void update(int nod)
{
    for(int i = 1; i < LMAX; i++)
    {
        TT[nod][i] = TT[TT[nod][i - 1]][i - 1];
        C[nod][i] = max(C[nod][i - 1], C[TT[nod][i - 1]][i - 1]);
    }
}

void dfs(int nod, int dad)
{
    viz[nod] = true;
    TT[nod][0] = dad;
    update(nod);
    lvl[nod] = lvl[dad] + 1;
    for(size_t i = 0; i < V[nod].size(); i++)
    {
        int neighbour = G[V[nod][i]].s.f + G[V[nod][i]].s.s - nod, cost = G[V[nod][i]].f;
        if(neighbour == dad) continue;
        C[neighbour][0] = cost;
        dfs(neighbour, nod);
    }
}

int LCA(int A, int B)
{
    int rez = 0;
    //daca nodul B e mai jos ca nodul A le interschimb
    if(lvl[B] > lvl[A]) swap(A, B);
    //il aduc pe A la acelasi nivel cu B
    for(int diff = lvl[A] - lvl[B], i = 0; diff && i < LMAX; i++)
        if(diff & (1 << i))
        {
            diff -= (1 << i);
            rez = max(rez, C[A][i]);
            A = TT[A][i];
        }
    if(A != B)
        for(int i = LMAX - 1; i >= 0; i--)
            if(TT[A][i] != TT[B][i])
            {
                rez = max(rez, max(C[A][i], C[B][i]));
                A = TT[A][i], B = TT[B][i];
            }
    return (A != B ? max(rez, max(C[A][0], C[B][0])) : rez);
}

int main()
{
    ifstream in("radiatie.in"); in>>N>>M>>K;
    for(int i = 1; i <= M; i++)
        in>>G[i].s.f>>G[i].s.s>>G[i].f;
    //APM
    sort(G + 1, G + M + 1);
    for(int i = 1; i <= N; i++) dad[i] = i, cnt[i] = 1;
    for(int i = 1, X, Y; i <= M; i++)
    {
        X = Find(G[i].s.f), Y = Find(G[i].s.s);
        if(X != Y)
        {
            Merge(X, Y);
            V[G[i].s.f].pb(i); V[G[i].s.s].pb(i);
        }
    }
    //construiesc vectorii cu tatii/costurile
    for(int i = 1; i <= N; i++)
        if(!viz[i])
            dfs(i, 0);
    ofstream out("radiatie.out");
    for(int i = 1, A, B; i <= K; i++)
    {
        in>>A>>B;
        out<<LCA(A, B)<<"\n";
    } in.close(); out.close();
    return 0;
}