Cod sursa(job #2296677)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 4 decembrie 2018 22:01:29
Problema Radiatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <bits/stdc++.h>

#define inf  (int)(1e9)
#define MAXN 15005
#define LOGN 15
#define int_pair std::pair <int, int>

int N, M, K;
std::vector <int_pair> ADC[MAXN];
std::vector <int> MSTADC[MAXN];

inline void AddEdge(int x, int y, int w) {
    ADC[x].push_back({y, w});
    ADC[y].push_back({x, w});
}

int Parent[LOGN][MAXN];
int Key[LOGN][MAXN];
std::priority_queue <int_pair, std::vector <int_pair>, std::greater <int_pair>> PQ;
std::bitset <MAXN> InMST;

void Prim(int Key[]) {
    for (int i=1; i<=N; ++i)
        Key[i] = inf;
    Key[1] = 0;
    PQ.push({0, 1});

    int_pair Top;
    while (!PQ.empty()) {
        Top = PQ.top();
        PQ.pop();

        if (Top.first > Key[Top.second]) continue;
        InMST[Top.second] = 1;

        for (auto Edge:ADC[Top.second]) {
            if (!InMST[Edge.first] && Edge.second < Key[Edge.first])
                Key[Edge.first] = Edge.second,
                Parent[0][Edge.first] = Top.second,
                PQ.push({Edge.second, Edge.first});}
    }
}

int Height[MAXN];
std::queue <int> Queue;

void BFS(int Source = 1) {
    Height[Source] = 1;
    Queue.push(Source);

    int Front;
    while (!Queue.empty()) {
        Front = Queue.front();
        Queue.pop();

        for (auto Vecin:MSTADC[Front])
            Queue.push(Vecin),
            Height[Vecin] = Height[Front] + 1;
    }
}

std::ifstream In("radiatie.in");
std::ofstream Out("radiatie.out");

void BuildMST() {
    Prim(Key[0]);
    for (int i=1; i<=N; ++i)
        MSTADC[Parent[0][i]].push_back(i);
    BFS();

    for (int k=1, i; (1<<k)<=N; ++k)
        for (i=1; i<=N; ++i)
            if (Height[i] >= (1>>k))
                Parent[k][i] = Parent[k-1][Parent[k-1][i]],
                Key[k][i] = std::max(Key[k-1][i], Key[k-1][Parent[k-1][i]]);
}

int LCA(int A, int B) {
    if (Height[A] < Height[B]) std::swap(A, B);

    int LOG1 = 1, LOG2 = 1;
    int MAX = 0;
    while ((1<<LOG1) < Height[A]) ++ LOG1;
    while ((1<<LOG2) < Height[B]) ++ LOG2;

    for (int k = LOG1; k>=0; --k)
        if (Height[A] - (1<<k) >= Height[B])
            MAX = std::max(MAX, Key[k][A]),
            A = Parent[k][A];

    if (A == B) return MAX;

    for (int k = LOG2; k>=0; --k)
        if (Parent[k][A] && Parent[k][A] != Parent[k][B])
            MAX = std::max(std::max(Key[k][A], Key[k][B]), MAX),
            A = Parent[k][A],
            B = Parent[k][B];
    MAX = std::max(std::max(Key[0][A], Key[0][B]), MAX);

    return MAX;
}

void Citire() {
    In >> N >> M >> K;
    for (int i=0, x, y, w; i<M; ++i)
        In >> x >> y >> w, AddEdge(x, y, w);
}

void Rezolvare() {
    BuildMST();

    int x, y;
    while (K--)
        In >> x >> y,
        Out << LCA(x, y) << '\n';
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}