Cod sursa(job #744429)

Utilizator mihai995mihai995 mihai995 Data 8 mai 2012 18:07:39
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 15005, M = 30005, LG = 15;
int T[LG][N], C[LG][N], dad[N], D[N], depth[N], n, m;
bool use[N];

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

struct Nod
{
    int x, c;

    Nod()
    {
        x = c = 0;
    }

    Nod(int _x, int _c)
    {
        x = _x;
        c = _c;
    }
};

struct Muchie
{
    int x, y, c;

    Muchie()
    {
        x = y = c = 0;
    }

    Muchie(int _x, int _y, int _c)
    {
        x = _x;
        y = _y;
        c = _c;
    }

    inline void get()
    {
        in >> x >> y >> c;
    }

    inline bool operator< (const Muchie& M) const
    {
        return c < M.c;
    }
} edge[M];

vector<Nod> graph[N];

inline int max(int a, int b)
{
    return a > b ? a : b;
}

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

bool merge(int x, int y)
{
    x = tata(x);
    y = tata(y);

    if (x == y)
        return false;

    if (D[x] < D[y])
    {
        dad[x] = y;
        D[y] = max(D[y], D[x] + 1);
    }
    else
    {
        dad[y] = x;
        D[x] = max(D[x], D[y] + 1);
    }
    return true;
}

void add(int x, int y, int c)
{
    if (!merge(x, y))
        return;

    graph[x].push_back(Nod(y, c));
    graph[y].push_back(Nod(x, c));
}

void apm()
{
    for (int i = 1 ; i <= n ; i++)
    {
        dad[i] = i;
        D[i] = 1;
    }
    sort(edge + 1, edge + m + 1);

    for (int i = 1 ; i <= m ; i++)
        add(edge[i].x, edge[i].y, edge[i].c);
}

void dfs(int x)
{
    use[x] = true;

    for (vector<Nod> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
    {
        int y = (*it).x;
        if (use[y])
            return;
        depth[y] = depth[x] + 1;
        T[0][y] = x;
        C[0][y] = (*it).c;
        dfs(y);
    }
}

void stramosi()
{
    for (int i = 1 ; i < LG ; i++)
        for (int j = 1 ; j <= n ; j++)
        {
            T[i][j] = T[i - 1][ T[i - 1][j] ];
            C[i][j] = max(C[i - 1][j], C[i - 1][ T[i - 1][j] ]);
        }
}

int tata(int x, int L)
{
    if ( L < 1 )
        return x;
    for (int i = LG - 1 ; i >= 0 ; i--)
        if ((1 << i) <= L)
        {
            L -= 1 << i;
            x = T[i][x];
        }
    return x;
}

int cost(int x, int L)
{
    int rez = 0;

    for (int i = LG - 1 ; i >= 0 ; i--)
        if ((1 << i) <= L)
        {
            L -= 1 << i;
            rez = max(rez, C[i][x]);
            x = T[i][x];
        }

    return rez;
}

int lca(int x, int y)
{
    x = tata(x, depth[x] - depth[y]);
    y = tata(y, depth[y] - depth[x]);

    if (x == y)
        return x;

    for (int i = LG - 1 ; i >= 0 ; i--)
        if (T[i][x] && T[i][x] != T[i][y])
        {
            x = T[i][x];
            y = T[i][y];
        }
    return T[0][x];
}

int main()
{
    int t, x, y, L, c;

    in >> n >> m >> t;

    for (int i = 1 ; i <= m ; i++)
        edge[i].get();

    apm();

    dfs(1);

    stramosi();

    while (t--)
    {
        in >> x >> y;

        L = depth[lca(x, y)];

        out << max(cost(x, depth[x] - L), cost(y, depth[y] - L)) << "\n";
    }

    return 0;
}