Cod sursa(job #2405786)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 14 aprilie 2019 22:15:24
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

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

const int NMax = 15000, MMax = 30000;

int N, M, T, TT[NMax + 5], H[NMax + 5], Lev[NMax + 5], A[20][NMax + 5], DP[20][NMax + 5], Viz[NMax + 5];
struct muchie{int a, b, c;} V[MMax + 5];

vector <pair<int, int> > G[NMax + 5];

inline bool compare(muchie A, muchie B) {return A.c < B.c;}

int Root(int Nod)
{
    while(Nod != TT[Nod])
        Nod = TT[Nod];

    return Nod;
}

void Unite(int A, int B)
{
    if(H[A] < H[B]) TT[A] = B;
    if(H[A] > H[B]) TT[B] = A;
    if(H[A] == H[B])TT[B] = A, H[A]++;
}

void Kruskal()
{
    sort(V + 1, V + M + 1, compare);

    for(int i = 1; i <= N; i++)
        H[i] = 1, TT[i] = i;

    for(int i = 1, R1, R2; i <= M; i++)
    {
        R1 = Root(V[i].a), R2 = Root(V[i].b);

        if(R1 != R2)
        {
            Unite(R1, R2);
            G[V[i].a].push_back({V[i].b, V[i].c});
            G[V[i].b].push_back({V[i].a, V[i].c});
        }
    }
}

void DFS(int Nod, int Tata)
{
    Lev[Nod] = Lev[Tata] + 1, Viz[Nod] = 1, A[0][Nod] = Tata;

    for(auto Vecin : G[Nod])
    {
        if(!Viz[Vecin.first])
            DFS(Vecin.first, Nod), DP[0][Vecin.first] = Vecin.second;
    }
}

void Precalc()
{
    for(int i = 1; (1 << i) <= N; i++)
        for(int j = 1; j <= N; j++)
        {
            A[i][j] = A[i - 1][A[i - 1][j]];

            if(A[i][j]) DP[i][j] = max(DP[i - 1][j], DP[i - 1][A[i - 1][j]]);
        }
}

int Stramos(int Nod, int L)
{
    int k = 0;

    while(L)
    {
        if(L & 1) Nod = A[k][Nod];
        L >>= 1, k++;
    }
    return Nod;
}

int LCA(int X, int Y)///lev X > lev Y
{
    if(Lev[X] < Lev[Y]) swap(X, Y);

    X = Stramos(X, Lev[X] - Lev[Y]);

    if(X == Y) return X;

    for(int i = log2(Lev[X]); i >= 0; i--)
    {
        if(A[i][X] != A[i][Y])
            X = A[i][X], Y = A[i][Y];
    }
    return A[0][X];
}

int Dist(int X, int Y)
{
    if(Lev[X] < Lev[Y]) swap(X, Y);

    int Ans = 0, L = Lev[X] - Lev[Y], k = 0;

    while(L)
    {
        if(L & 1) Ans = max(DP[k][X], Ans), X = A[k][X];
        k++, L >>= 1;
    }
    return Ans;
}

int main()
{
    fin >> N >> M >> T;

    for(int i = 1, a, b, c; i <= M; i++)
    {
        fin >> a >> b >> c;
        V[i] = {a, b, c};
    }
    Kruskal(); DFS(1, 0); Precalc();

    while(T--)
    {
        int a, b, Nod;

        fin >> a >> b; Nod = LCA(a, b);

        fout << max(Dist(a, Nod), Dist(b, Nod)) << '\n';
    }
    fin.close();
    fout.close();

    return 0;
}