Cod sursa(job #942023)

Utilizator SteveStefan Eniceicu Steve Data 20 aprilie 2013 15:22:42
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define MAXN 15011
#define MAXM 30011
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) {
    if (x.c == y.c) return x.a < y.a;
    return x.c < y.c;
}

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

inline void Unite (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 () {
    for (int i = 0; i < M; i++)
    {
        if (Parent (muchii[i].a) == Parent (muchii[i].b)) continue;
        Unite (muchii[i].a, muchii[i].b);
        G[muchii[i].a].push_back (make_pair (muchii[i].b, muchii[i].c));
        G[muchii[i].b].push_back (make_pair (muchii[i].a, muchii[i].c));
    }
}

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].first]) DFS (G[nod][i].first, nod, depth + 1, G[nod][i].second), 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];
}

inline 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].first = i, point[i].second = 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);
        if (D[c] > D[a] || D[c] > D[b]) stramos[1][10000] = 1;
        fout << max (Query (a, c), Query (b, c)) << "\n";
    }
    fin.close ();
    fout.close ();
    return 0;
}