Cod sursa(job #2109237)

Utilizator papinub2Papa Valentin papinub2 Data 19 ianuarie 2018 12:46:18
Problema Radiatie Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define mp make_pair

using namespace std;

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

const int Nmax = 15005;
const int Mmax = 30005;

int n, m, k, nr;
int dad[Nmax], nivel[Nmax], logaritm[Nmax];
bool viz[Nmax];

int dp[15][Nmax], rmq[15][Nmax];

vector<pair<int, int>> APM[Nmax];

struct graf
{
    int x;
    int y;
    int c;
}v[Mmax];

bool cmp (graf A, graf B)
{
    return A.c < B.c;
}

int Find (int x)
{
    if (dad[x] == x) return x;
    return dad[x] = Find (dad[x]);
}

void Union (int x, int y)
{
    dad[x] = y;
}

void DFS (int p)
{
    viz[p] = 1;

    for (auto i = 0; i < APM[p].size(); i++)
    {
        int w = APM[p][i].first;

        if (!viz[w])
        {
            rmq[0][w] = APM[p][i].second;
            dp[0][w] = p;
            nivel[w] = nivel[p] + 1;
            DFS(w);
        }
    }
}

int lca (int x, int y)
{
    int log1, log2;

    if (nivel[x] < nivel[y])
        swap (x, y);

    for (log1 = 1; (1<<log1) < nivel[x]; log1++);
    for (log2 = 1; (1<<log2) < nivel[y]; log2++);

    for (int i = log1; i >= 0; i--)
        if (nivel[x] - (1<<i) >= nivel[y])
            x = dp[i][x];

    if (x == y)
        return x;

    for (int i = log2; i >= 0; i--)
        if (dp[i][x] && dp[i][x] != dp[i][y])
        {
            x = dp[i][x];
            y = dp[i][y];
        }

    return dp[0][x];
}

int main()
{
    in >> n >> m >> k;

    dad[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        dad[i] = i;
        logaritm[i] = logaritm[i / 2] + 1;
    }

    for (int i = 1; i <= m; i++)
        in >> v[i].x >> v[i].y >> v[i].c;

    sort (v + 1, v + m + 1, cmp);

    for (int i = 1; i <= m; i++)
    {
        if (nr == n - 1)
            break;

        int xx = Find(v[i].x);
        int yy = Find(v[i].y);

        if (xx != yy)
        {
            nr++;
            Union (xx, yy);

            APM[v[i].x].push_back(mp(v[i].y, v[i].c));
            APM[v[i].y].push_back(mp(v[i].x, v[i].c));
        }
    }

    nivel[1] = 1;
    DFS(1);

    for (int i = 1; (1<<i) <= n; i++)
        for (int j = 1; j <= n; j++)
            dp[i][j] = dp[i - 1][dp[i - 1][j]];

    for (int i = 1; (1 << i) <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (nivel[j] < (1 << i)) continue;
            rmq[i][j] = max(rmq[i - 1][j], rmq[i - 1][dp[i - 1][j]]);
        }

    for (int i = 1; i <= k; i++)
    {
        int x, y, rez1 = 0, rez2 = 0;
        in >> x >> y;

        int L = lca (x, y);

        int dist1 = nivel[x] - nivel[L];
        int dist2 = nivel[y] - nivel[L];

        int log1 = logaritm[dist1];
        int log2 = logaritm[dist2];

        if (log1 > 0)
        {
            if (dist1 - (1<<log1) - 1 >= 0)
                rez1 = max (rmq[log1][x], rmq[log1][dp[logaritm[dist1 - (1<<log1) - 1]][x]]);
            else
                rez1 = rmq[log1][x];
        }
            else
            if (x != L)
                rez1 = rmq[log1][x];

        if (log2 > 0)
        {
            if (dist2 - (1<<log2) - 1 >= 0)
                rez2 = max (rmq[log2][y], rmq[log2][dp[logaritm[dist2 - (1<<log2) - 1]][y]]);
            else
                rez2 = rmq[log2][y];
        }
            else
            if (y != L)
                rez2 = rmq[log2][y];

        out << max (rez1, rez2) << '\n';
    }

    return 0;
}