Cod sursa(job #1759649)

Utilizator preda.andreiPreda Andrei preda.andrei Data 19 septembrie 2016 17:50:11
Problema Radiatie Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <tuple>

using namespace std;

#define NMAX 15001
#define NODURI_NIVEL 200

typedef tuple<int, int, int> ElemCoada;

struct Nod
{
    int nivel;
    int adancime;
    int tata;
    int costTata;
    int stramos;
};

Nod noduri[NMAX];
vector< pair<int, int> > muchii[NMAX];
int maxNivel[NMAX / NODURI_NIVEL + 1];

bool cmp(ElemCoada &a, ElemCoada &b)
{
    return get<0>(a) > get<0>(b);
}

void construiesteArbore(int n)
{
    priority_queue<ElemCoada, vector<ElemCoada>, decltype(&cmp)> q(&cmp);
    q.push(make_tuple(0, 0, 1));
    noduri[1] = {1, 1, 0, 0, 0};

    vector<bool> vizitat;
    vizitat.assign(n + 1, false);

    for (int i = 1; i <= n; ++i) {
        while (vizitat[get<2>(q.top())])
            q.pop();

        int cost = get<0>(q.top());
        int src = get<1>(q.top());
        int dest = get<2>(q.top());
        q.pop();

        vizitat[dest] = true;

        noduri[dest].tata = src;
        noduri[dest].costTata = cost;
        noduri[dest].stramos = src;
        noduri[dest].nivel = noduri[src].nivel;
        noduri[dest].adancime = noduri[src].adancime + 1;

        if (noduri[dest].adancime > NODURI_NIVEL) {
            noduri[dest].adancime = 1;
            ++noduri[dest].nivel;
            noduri[dest].stramos = src;
        }

        maxNivel[noduri[dest].nivel] = max(maxNivel[noduri[dest].nivel], cost);

        for (auto muchie : muchii[dest]) {
            if (!vizitat[muchie.first]) {
                q.push(make_tuple(muchie.second, dest, muchie.first));
            }
        }
    }
}

int gasesteLCA(int x, int y)
{
    while (noduri[x].nivel != noduri[y].nivel) {
        if (noduri[x].nivel > noduri[y].nivel)
            x = noduri[x].stramos;
        else y = noduri[y].stramos;
    }
    while (x != y) {
        if (noduri[x].adancime > noduri[y].adancime)
            x = noduri[x].tata;
        else y = noduri[y].tata;
    }

    return x;
}

int maxRadiatie(int start, int stop)
{
    int maxim = 0;
    int stramosInitial = noduri[start].stramos;

    while (start != stop && start != stramosInitial) {
        maxim = max(maxim, noduri[start].costTata);
        start = noduri[start].tata;
    }

    while (noduri[start].nivel != noduri[stop].nivel) {
        maxim = max(maxim, maxNivel[noduri[start].nivel]);
        start = noduri[start].stramos;
    }

    while (start != stop) {
        maxim = max(maxim, noduri[start].costTata);
        start = noduri[start].tata;
    }

    return maxim;
}

int aflaRadiatie(int x, int y)
{
    int rad = gasesteLCA(x, y);
    return max(maxRadiatie(x, rad), maxRadiatie(y, rad));
}

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

    int n, m, k;
    fin >> n >> m >> k;

    while (m--) {
        int x, y, c;
        fin >> x >> y >> c;
        muchii[x].push_back({y, c});
        muchii[y].push_back({x, c});
    }

    construiesteArbore(n);

    while (k--) {
        int x, y;
        fin >> x >> y;
        fout << aflaRadiatie(x, y) << "\n";
    }

    return 0;
}