Cod sursa(job #942041)

Utilizator SteveStefan Eniceicu Steve Data 20 aprilie 2013 16:10:24
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.53 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define MAXN 15011
#define MAXM 30011
#define pb push_back
#define mp(a, b) make_pair (a, b)
#define f first
#define s second
using namespace std;

typedef struct  {
    int a;
    int b;
    int c;
} mystruct;

int N, M, K, cnt = -1;
mystruct muchii[MAXM];
int viz[MAXN];
int Rep_Euler[MAXM];
int indice[MAXN];
int D[MAXN];
int stramos[MAXN][14];
int Val[MAXN][14];
int ST[MAXM][15];
pair <int, int> point[MAXN];
vector <pair <int, int> > G[MAXN];

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

inline int cmp (mystruct x, mystruct y) {
    return x.c < y.c;
}

int Parent (int x) {
    if (x == point[x].f) return x;
    return point[x].f = Parent (point[x].f);
}

void Unite (int x, int y) {
    x = Parent (x);
    y = Parent (y);
    if (point[x].s > point[y].s) point[y].f = x, point[x].s += point[y].s;
    else point[x].f = y, point[y].s += point[x].s;
}

void Kruskal () {
    for (int i = 0; i < M; i++)
    {
        int x = muchii[i].a, y = muchii[i].b, ct = muchii[i].c;
        if (Parent (x) != Parent (y))
        {
            Unite (x, y);
            G[x].pb (mp (y, ct));
            G[y].pb (mp (x, ct));
        }
    }
}

void DFS (int nod, int parent, int depth, int last_edge) {
    viz[nod] = 1;
    Rep_Euler[++cnt] = nod;
    indice[nod] = cnt;
    D[nod] = depth;
    stramos[nod][0] = parent;
    Val[nod][0] = last_edge;
    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]);
    }
    for (int i = 0; i < G[nod].size (); i++)
        if (!viz[G[nod][i].f]) DFS (G[nod][i].f, nod, depth + 1, G[nod][i].s), Rep_Euler[++cnt] = nod;
}

void Make_ST () {
    for (int i = 0; i <= cnt; i++)
        ST[i][0] = i;
    for (int j = 1; 1 << j <= cnt + 1; j++)
        for (int i = 0; i + (1 << j) <= cnt + 1; 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]]);
}

int Query (int x, int y)
{
    int val = 0, j;
    while (D[x] >= D[y])
    {
        for (j = 0; stramos[x][j] && D[stramos[x][j]] >= D[y]; j++);
        j--;
        val = max (val, Val[x][j]);
        x = stramos[x][j];
    }
    return val;
}

int main ()
{
    ifstream fin ("radiatie.in");
    ofstream fout ("radiatie.out");
    fin >> N >> M >> K;
    for (int i = 0; i < M; i++)
        fin >> muchii[i].a >> muchii[i].b >> muchii[i].c;
    for (int i = 1; i <= N; i++)
        point[i].f = i, point[i].s = 1;
    sort (muchii, muchii + M, cmp);
    Kruskal ();
    for (int i = 1; i <= N; i++)
        if (!viz[i]) DFS (i, 0, 1, 0);
    Make_ST ();
    for (int a, b, c; K; K--)
    {
        fin >> a >> b;
        c = LCA (a, b);
        int Ans = 0;
        while (a != c)
        {
            Ans = max (Ans, Val[a][0]);
            a = stramos[a][0];
        }
        while (b != c)
        {
            Ans = max (Ans, Val[b][0]);
            b = stramos[b][0];
        }
        fout << Ans << "\n";//max (Query (a, c), Query (b, c)) << "\n";
    }
    fin.close ();
    fout.close ();
    return 0;
}