Cod sursa(job #941860)

Utilizator SteveStefan Eniceicu Steve Data 19 aprilie 2013 22:04:43
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.51 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#define TR(C, it) for (typeof (C.begin ()) it = C.begin (); it != C.end (); it++)
using namespace std;

int N, M, K, cnt = -1, cnt1 = -1;
pair <int, pair <int, int> > muchii[30011];
vector <pair <int, int> > G[15011];
pair <int, int> point[15011];
int Rep_Euler[30011];
int viz[15011];
int ST[30011][17];
int indice[15011];
int Adancime[15011];
int stramos[15011][16];
int Val[15011][16];

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

int min (int a, int b)
{
    return (a < b ? a : b);
}

int Parent (int nod)
{
    if (!point[nod].first) return nod;
    return point[nod].first = Parent (point[nod].first);
}

void Unite_DDS (int x, int y)
{
    x = Parent (x);
    y = Parent (y);
    if (point[x].second > point[y].second) point[y].first = x, point[x].second += point[y].second;
    else point[x].first = y, point[y].second += point[x].second;
}

void Kruskal ()
{
    ofstream dog ("dog.out");
    for (int i = 0; i <= cnt1; i++)
    {
        int x = muchii[i].second.first;
        int y = muchii[i].second.second;
        if (Parent (x) == Parent (y)) continue;
        Unite_DDS (x, y);
        G[x].push_back (make_pair (y, muchii[i].first));
        G[y].push_back (make_pair (x, muchii[i].first));
        dog << x << " " << y << "\n";
    }
}

void DFS (int nod)
{
    Rep_Euler[++cnt] = nod;
    indice[nod] = cnt;
    TR (G[nod], it)
        if (indice[it -> first] == -1) DFS (it -> first), Rep_Euler[++cnt] = nod;
}

void Make_ST ()
{
    for (int i = 0; i <= cnt; i++)
        ST[i][0] = i;
    for (int j = 1; (1 << j) - 1 <= cnt; j++)
        for (int i = 0; i + (1 << j) - 1 <= cnt; i++)
            if (Rep_Euler[ST[i][j - 1]] < Rep_Euler[ST[i + (1 << (j - 1))][j - 1]]) ST[i][j] = ST[i][j - 1];
            else ST[i][j] = ST[i + (1 << (j - 1))][j - 1];
}

int LCA (int i, int j)
{
    i = indice[i];
    j = indice[j];
    if (i > j) swap (i, j);
    int k;
    for (k = 0; 1 << k <= j - i + 1; k++);
    k--;
    return min (Rep_Euler[ST[i][k]], Rep_Euler[ST[j - (1 << k) + 1][k]]);
}

void DFS2 (int nod, int parinte, int depth, int last_cost)
{
    stramos[nod][0] = parinte;
    Val[nod][0] = last_cost;
    viz[nod] = 1;
    Adancime[nod] = depth;
    for (int j = 1; 1 << j <= depth; j++)
    {
        stramos[nod][j] = stramos[stramos[nod][j - 1]][j - 1];
        Val[nod][j] = max (Val[nod][j - 1], Val[stramos[nod][j - 1]][j - 1]);
    }
    TR (G[nod], it)
        if (!viz[it -> first]) DFS2 (it -> first, nod, depth + 1, it -> second);
}

int Query (int x, int y)
{
    if (x == y) return 0;
    int k;
    for (k = 0; 1 << k <= Adancime[x] - Adancime[y]; k++);
    k--;
    return max (Val[x][k], Query (stramos[x][k], y));
}

int main ()
{
    ifstream fin ("radiatie.in");
    ofstream fout ("radiatie.out");
    fin >> N >> M >> K;
    for (int i = 1, a, b, c; i <= M; i++)
    {
        fin >> a >> b >> c;
        muchii[++cnt1] = make_pair (c, make_pair (a, b));
    }
    memset (indice, -1, sizeof (indice));
    sort (muchii, muchii + M + 1);
    Kruskal ();
    for (int i = 1; i <= N; i++)
        if (indice[i] == -1) DFS (i);
    Make_ST ();
    for (int i = 1; i <= N; i++)
        if (!viz[i]) DFS2 (i, 0, 1, 0);
    for (int i, j; K; K--)
    {
        fin >> i >> j;
        int x = LCA (i, j);
        fout << max (Query (i, x), Query (j, x)) << "\n";
    }
    fin.close ();
    fout.close ();
    return 0;
}