Cod sursa(job #895692)

Utilizator visanrVisan Radu visanr Data 27 februarie 2013 12:15:28
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

#define Nmax 15010
#define Emax 30010
#define PI pair<int, int>
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define PIT vector<PI> :: iterator
#define IT vector<int> :: iterator

int N, K, M, X[Emax], Y[Emax], Z[Emax], Idx[Emax], A, B;
int Ancestor[15][Nmax], AncestorCost[15][Nmax];
int Father[Nmax], Size[Nmax], Used[Nmax], Level[Nmax];
vector<PI> G[Nmax];

void UpdateAncestors(int Node)
{
    for(int i = 1; i < 15; i++)
    {
        Ancestor[i][Node] = Ancestor[i - 1][Ancestor[i - 1][Node]];
        AncestorCost[i][Node] = max(AncestorCost[i - 1][Node], AncestorCost[i - 1][Ancestor[i - 1][Node]]);
    }
}

void DFS(int Node, int Father)
{
    Used[Node] = 1;
    Ancestor[0][Node] = Father;
    UpdateAncestors(Node);
    Level[Node] = Level[Father] + 1;
    for(PIT it = G[Node].begin(); it != G[Node].end(); ++it)
        if(!Used[it -> f])
        {
            AncestorCost[0][it -> f] = it -> s;
            DFS(it -> f, Node);
        }
}

int Find_Root(int X)
{
    int P, Y;
    for(P = X; P != Father[P]; P = Father[P]);
    for(; X != Father[X]; )
    {
        Y = Father[X];
        Father[X] = P;
        X = Father[X];
    }
    return P;
}

void Merge(int X, int Y)
{
    if(Size[X] > Size[Y])
    {
        Size[X] += Size[Y];
        Father[Y] = X;
    }else
    {
        Size[Y] += Size[X];
        Father[X] = Y;
    }
}

struct CMP
{
    bool operator() (const int &A, const int &B) const
    {
        return Z[A] < Z[B];
    };
};

void DoAPM()
{
    sort(Idx + 1, Idx + M + 1, CMP());
    for(int i = 1; i <= N; ++i) Father[i] = i, Size[i] = 1;
    for(int i = 1; i <= M; ++ i)
    {
        int A = X[Idx[i]], B = Y[Idx[i]], C = Z[Idx[i]];
        if(Find_Root(A) != Find_Root(B))
        {
            Merge(Find_Root(A), Find_Root(B));
            G[A].pb(mp(B, C));
            G[B].pb(mp(A, C));
        }
    }
}

int GetCost(int A, int B)
{
    if(Level[A] < Level[B]) swap(A, B);
    int Step1, Step2, Ans = 0;
    for(Step1 = 1; (1 << Step1) < Level[A]; Step1 ++);
    for(Step2 = 1; (1 << Step2) < Level[B]; Step2 ++);
    for(; Step1 >= 0; Step1 --)
        if(Level[A] - (1 << Step1) >= Level[B])
        {
            Ans = max(Ans, AncestorCost[Step1][A]);
            A = Ancestor[Step1][A];
        }
    if(A == B) return Ans;
    for(; Step2 >= 0; Step2 --)
        if(Ancestor[Step2][A] && Ancestor[Step2][A] != Ancestor[Step2][B])
        {
            Ans = max(Ans, AncestorCost[Step2][A]);
            Ans = max(Ans, AncestorCost[Step2][B]);
            A = Ancestor[Step2][A];
            B = Ancestor[Step2][B];
        }
    Ans = max(Ans, AncestorCost[0][A]);
    Ans = max(Ans, AncestorCost[0][B]);
    return Ans;
}

int main()
{
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    int i, j;
    scanf("%i %i %i", &N, &M, &K);
    for(i = 1; i <= M; ++i)
    {
        scanf("%i %i %i", &X[i], &Y[i], &Z[i]);
        Idx[i] = i;
    }
    DoAPM();
    for(i = 1; i <= N; i++)
        if(!Used[i])
            DFS(i, 0);
    for(i = 1; i <= K; i++)
    {
        scanf("%i %i", &A, &B);
        printf("%i\n", GetCost(A, B));
    }
    return 0;
}