Cod sursa(job #1399194)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 24 martie 2015 17:05:28
Problema Radiatie Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

const int MAXN = 15000 + 10;
typedef pair <int, int> PII;

struct edge
{
    int a, b, c;
} X[MAXN * 2];//graful initial

int now;//indicele pentru parcurgerea Euler
int N, M, K;//numerele din cerinta
vector <PII> Graf[MAXN];//APM-ul
int H[MAXN * 2];//parcurgerea Euler
int Lvl[MAXN * 2];//nivelul pe care apare nodul i
int First[MAXN];//prima pozitie in parcurgere pe care apare nodul i
int D[14][MAXN];//al 2^i-lea stramos al nodului j
int Smen[14][MAXN];//maximul pe drumul de la nodul j pana la al 2^i-lea stramos al sau
int RMQ[14][MAXN * 2];//nivelul maxim pe intervale din parcurgerea Euler
int Log[MAXN * 2];//logaritmul numarului i
int T[MAXN];//pt padurea de multimi disjuncte pt APM
bool Viz[MAXN];//pt parcurgerea in adancime pt constructie
PII Queries[MAXN];

struct comp
{
    inline bool operator () (const edge &A, const edge &B) const
    {
        return A.c < B.c;
    }
};

int find (int node)
{
    if (T[node] == node)
        return node;

    T[node] = find (T[node]);
    return T[node];
}

void Build_APM ()
{
    sort (X + 1, X + M + 1, comp ());

    int i, Tx, Ty;
    int a, b, c;

    for (i = 1; i <= M; i ++){
        a = X[i].a;
        b = X[i].b;
        c = X[i].c;

        Tx = find (a);
        Ty = find (b);

        if (Tx != Ty){
            Graf[a].push_back (make_pair (b, c));
            Graf[b].push_back (make_pair (a, c));

            T[Tx] = Ty;
        }
    }
}

void DFS (int node, int val, int father, int lev)
{
    ++ now;
    H[now] = node;
    First[node] = now;
    Lvl[now] = lev;
    Viz[node] = 1;
    D[0][node] = father;
    Smen[0][node] = val;

    vector <PII> :: iterator it;

    for (it = Graf[node].begin (); it != Graf[node].end (); ++ it)
        if (!Viz[it -> first]){
            DFS (it -> first, it -> second, node, lev + 1);

            ++ now;
            H[now] = node;
            Lvl[now] = lev;
        }
}

void Build_Log ()
{
    int i;

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

void Build_RMQ ()
{
    int i, j, a, b;

    for (i = 1; i <= now; i ++)
        RMQ[0][i] = i;

    for (i = 1; (1 << i) < now; i ++)
        for (j = 1; j + (1 << i) <= now; j ++){
            a = RMQ[i - 1][j];
            b = RMQ[i - 1][j + (1 << (i - 1))];

            if (Lvl[a] <= Lvl[b])
                RMQ[i][j] = a;
            else
                RMQ[i][j] = b;
        }
}

int LCA (int x, int y)
{
    x = First[x];
    y = First[y];

    if (x > y)
        swap (x, y);

    int dif = y - x + 1;
    int lg = Log[dif];
    int a, b;
    a = RMQ[lg][x];
    b = RMQ[lg][y - (1 << lg) + 1];

    if (Lvl[a] <= Lvl[b])
        return H[a];
    else
        return H[b];
}

void Build_Smen ()
{
    int i, j;

    for (i = 1; (1 << i) <= N; i ++)
        for (j = 1; j <= N; j ++){
            D[i][j] = D[i - 1][ D[i - 1][j] ];
            Smen[i][j] = max (Smen[i - 1][j], Smen[i - 1][ D[i - 1][j] ]);
        }
}

int Query (int x, int y)
{
    int dif, i;
    int Ans = -1;

    dif = Lvl[First[x]] - Lvl[First[y]];

    for (i = 0; (1 << i) <= dif; i ++)
        if (dif & (1 << i)){
            Ans = max (Ans, Smen[i][x]);
            x = D[i][x];
        }

    return Ans;
}

int Solve (int x, int y)
{
    int lca = LCA (x, y);
    int a, b;
    a = Query (x, lca);
    b = Query (y, lca);

    if (a > b)
        return a;
    else
        return b;
}

void Read ()
{
    in >> N >> M >> K;

    int i, x, y;

    for (i = 1; i <= M; i ++)
        in >> X[i].a >> X[i].b >> X[i].c;

    for (i = 1; i <= K; i ++)
        in >> Queries[i].first >> Queries[i].second;

    for (i = 1; i <= N; i ++)
        T[i] = i;
}

void Solve_Queries ()
{
    int i;

    for (i = 1; i <= K; i ++)
        out << Solve (Queries[i].first, Queries[i].second) << "\n";
}

int main()
{
    Read ();
    Build_APM ();
    DFS (1, 0, 0, 1);
    Build_Log ();
    Build_RMQ ();
    Build_Smen ();
    Solve_Queries ();

    return 0;
}