Cod sursa(job #6776)

Utilizator dominoMircea Pasoi domino Data 20 ianuarie 2007 22:24:26
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define MAX_N 15005
#define MAX_LG 15
#define MAX_M 30005
#define MAX_Q 65535
#define INF 1000000666
#define FIN "radiatie.in"
#define FOUT "radiatie.out"
#define FOR(i, a, b) for (i = (a); i < (b); i++)
#define f first
#define s second
#define mp make_pair

typedef pair<int, int> PII;

int N, M, K, deg[MAX_N], D[MAX_N], lev[MAX_N], lg[MAX_N], up[MAX_N];
pair<int, PII > E[MAX_M]; PII *G[MAX_N], J[MAX_LG][MAX_N];
char ok[MAX_M];

inline int find(int n)
{
    if (n != up[n]) up[n] = find(up[n]);
    return up[n];
}

inline void reunion(int i, int j)
{
    if (rand()&1) up[i] = j; else up[j] = i;
}

void kruskal(void)
{
    int i, j, m, c;

    sort(E, E+M);
    FOR (i, 1, N+1) up[i] = i;
    FOR (m, 0, M)
    {
        c = E[m].f, i = E[m].s.f, j = E[m].s.s;
        if (find(i) == find(j)) continue;
        reunion(find(i), find(j));
        ok[m] = 1;
    }
}

void DFS(int n)
{
    PII *p;
    int t;
    
    for (t = 0; (1<<(t+1)) <= lev[n]; t++)
    {
        J[t+1][n].f = J[t][J[t][n].f].f;
        J[t+1][n].s = max(J[t][n].s, J[t][J[t][n].f].s);
    }

    for (p = G[n]; p->f; p++)
        if (p->f != J[0][n].f)
        {
            lev[p->f] = lev[n]+1;
            J[0][p->f] = mp(n, p->s);
            DFS(p->f);
        }
}

int query(int x, int y)
{
    int t, ret = -INF;
    
    for (; lev[x] < lev[y]; y = J[lg[lev[y]-lev[x]]][y].f)
        ret = max(ret, J[lg[lev[y]-lev[x]]][y].s);

    for (; lev[x] > lev[y]; x = J[lg[lev[x]-lev[y]]][x].f)
        ret = max(ret, J[lg[lev[x]-lev[y]]][x].s);

    if (x == y) return ret;

    for (t = lg[lev[x]]; t >= 0; t--)
    {
        if (J[t][x].f == J[t][y].f) continue;
        ret = max(ret, J[t][x].s);
        ret = max(ret, J[t][y].s);
        x = J[t][x].f; y = J[t][y].f;
    }
    ret = max(ret, J[0][x].s); ret = max(ret, J[0][y].s);
    
    return ret;
}

int main(void)
{
    int m, i, j, c;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    // read stuff
    scanf("%d %d %d", &N, &M, &K);
    FOR (m, 0, M) { scanf("%d %d %d", &i, &j, &c); deg[i]++; deg[j]++; E[m] = mp(c, mp(i, j)); }
    
    kruskal();
    
    FOR (i, 1, N+1)
    {
        G[i] = (PII *) calloc(deg[i]+2, sizeof(PII));
        deg[i] = 0;
    }
    FOR (m, 0, M)
    {
        if (!ok[m]) continue;
        i = E[m].s.f, j = E[m].s.s, c = E[m].f;
        G[i][deg[i]++] = mp(j, c);
        G[j][deg[j]++] = mp(i, c);
    }

    // preprocess tree
    FOR (i, 1, N+1) if (!J[0][i].f) DFS(i);

    for (i = 2, j = 1; i < MAX_N; i++)
    {
        lg[i] = j;
        if ((1<<(j+1)) == i+1) j++;
    }

    // answer queries
    for (; K > 0; K--)
    {
        scanf("%d %d", &i, &j);
        printf("%d\n", query(i, j));
    }

    return 0;
}