Cod sursa(job #1644133)

Utilizator EpictetStamatin Cristian Epictet Data 9 martie 2016 21:39:22
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 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], Min_Cost[30010], First_Position[15010], Log[30010], RMQ[17][30010];
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 } );
        A[x.nod2].push_back( { x.nod1, 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 min_cost)
{
    k ++;
    Euler[k] = nod;
    Min_Cost[k] = min_cost;
    First_Position[nod] = k;
    F[nod] = true;

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

        k ++;
        Euler[k] = nod;
        Min_Cost[k] = it->second;
    }
}

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 (Min_Cost[RMQ[i - 1][j + lll]] > Min_Cost[RMQ[i][j]])
            {
                RMQ[i][j] = RMQ[i - 1][j + lll];
            }
        }
    }
}

void Solve_With_LCA()
{
    memset(F, 0, sizeof(F));
    for (int i = 1; i <= n; i ++)
    {
        if (!F[i])
        {
            DFS(i, 0);
        }
    }
    Solve_RMQ();

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

        int lin = Log[y - x + 1];
        int sol = max(Min_Cost[RMQ[lin][x]], Min_Cost[RMQ[lin][y - (1 << lin) + 1]]);
        fout << sol << '\n';
    }
    fout.close();
}

int main()
{
    Read();
    for (int i = 1; i <= n; i ++)
    {
        if (!F[i])
        {
            Prim(i);
        }
    }
    Solve_With_LCA();

    return 0;
}