Cod sursa(job #1644894)

Utilizator EpictetStamatin Cristian Epictet Data 10 martie 2016 10:10:22
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.96 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <set>

using namespace std;

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

struct APM { int cost, nod1, nod2; };
struct CMP_APM
{
    bool operator () (const APM &a, const APM &b)
    {
        return (a.cost < b.cost);
    }
};
int n, m, q, k, Euler[30010], Nivel[30010], First_Position[15010], Dad[15010], Cost[15010], Log[30010], RMQ[20][30010];
int STR[20][15010]; /// Al 2^i stramos al lui j
int STRMAX[20][15010]; /// Muchia de cost maxim intre j si 2^i lea stramos
vector < pair < int, int > > V[15010], A[15010];
multiset < APM, CMP_APM > H;
bool F[15010];

void Read()
{
    fin >> n >> m >> q;
    for (int i = 1, x, y, c; i <= m; i ++)
    {
        fin >> x >> y >> c;
        V[x].push_back( { y, c } );
        V[y].push_back( { x, c } );
    }
}

void Add_In_Heap(int nod)
{
    for (vector < pair < int, int > > :: iterator it = V[nod].begin(); it != V[nod].end(); it ++)
    {
        if (!F[it->first]) H.insert( { it->second, nod, it->first } );
    }
}

void Prim(int nod)
{
    F[nod] = true;
    Add_In_Heap(nod);

    for (int i = 1; i < n; i ++)
    {
        APM x = *H.begin();
        H.erase(*H.begin());
        A[x.nod1].push_back( { x.nod2, x.cost } );
        F[x.nod2] = true;
        Add_In_Heap(x.nod2);
        while (true && !H.empty())
        {
            x = *H.begin();
            if (!F[x.nod1] || !F[x.nod2]) break;
            H.erase(*H.begin());
        }
    }
}

void DFS(int nod, int level, int granpa, int costul)
{
    k ++;
    Euler[k] = nod;
    Dad[nod] = granpa;
    Nivel[k] = level;
    Cost[nod] = costul;
    First_Position[nod] = k;
    F[nod] = true;

    for (vector < pair < int, int > > :: iterator it = A[nod].begin(); it != A[nod].end(); it ++)
    {
        DFS(it->first, level + 1, nod, it->second);

        k ++;
        Euler[k] = nod;
        Nivel[k] = level;
    }
}

void Solve_RMQ()
{
    Log[0] = -1;
    for (int i = 1; i <= k; i ++)
    {
        Log[i] = Log[i / 2] + 1;
        RMQ[0][i] = i;
    }

    for (int i = 1; i <= Log[k]; i ++)
    {
        for (int j = 1; j <= k - (1 << i) + 1; j ++)
        {
            int lll = (1 << (i - 1));
            RMQ[i][j] = RMQ[i - 1][j];
            if (Nivel[RMQ[i - 1][j + lll]] < Nivel[RMQ[i][j]])
            {
                RMQ[i][j] = RMQ[i - 1][j + lll];
            }
        }
    }
}

void Stramosi()
{
    for (int i = 1; i <= n; i ++)
    {
        STR[0][i] = Dad[i];
        STRMAX[0][i] = Cost[i];
    }

    for (int i = 1; (1 << i) <= n; i ++)
    {
        for (int j = 1; j <= n; j ++)
        {
            STR[i][j] = STR[i - 1][STR[i - 1][j]];
            STRMAX[i][j] = STRMAX[i - 1][j];
            if (STRMAX[i - 1][STR[i - 1][j]] > STRMAX[i][j])
            {
                STRMAX[i][j] = STRMAX[i - 1][STR[i - 1][j]];
            }
        }
    }
}

int Cost_Stramos_La_Fiu_LOG(int t, int f)
{
    int sol = 0;
    while (Nivel[f] > Nivel[t])
    {
        int asdf = Log[Nivel[f] - Nivel[t]];
        sol = max(sol, STRMAX[asdf][f]);
        f = STR[asdf][f];
    }
    return sol;
}

void Solve_With_LCA()
{
    memset(F, 0, sizeof(F));
    DFS(1, 1, -1, 0);
    Solve_RMQ();
    Stramosi();

    for (int i = 1, x, y; i <= q; i ++)
    {
        fin >> x >> y;
        int xx = First_Position[x];
        int yy = First_Position[y];
        if (xx > yy) swap(xx, yy);

        int lin = Log[yy - xx + 1];
        int sol = RMQ[lin][xx];
        if (Nivel[RMQ[lin][yy - (1 << lin) + 1]] < Nivel[sol]) sol = RMQ[lin][yy - (1 << lin) + 1];
        int stramos_comun = Euler[sol];

        int final_sol = max(Cost_Stramos_La_Fiu_LOG(stramos_comun, x), Cost_Stramos_La_Fiu_LOG(stramos_comun, y));
        fout << final_sol << '\n';
    }
    fout.close();
}

int main()
{
    Read();
    Prim(1);
    Solve_With_LCA();

    return 0;
}