Cod sursa(job #1265869)

Utilizator SmarandaMaria Pandele Smaranda Data 17 noiembrie 2014 21:29:32
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.57 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int M = 30003, N = 15003;

struct Edge {
    int x, y, c;
};

struct Edge1 {
    int x, c;
};

vector <Edge1> graph [N];
Edge E [M], E2 [M];
int n, m, u = 0, fx, fy, maxx;
bool used [N];
int t [N], h [N], dp [15][N], dp2 [15][N], level [N];

class MyComp {
    public :
        bool operator () (const Edge &A, const Edge &B) {
            return A.c < B.c;
        }
};

int getFather (int x) {
    int T, father;
    for (T = x; t [T] != T; T = t [T]);
    father = T;
    while (x != father) {
        T = t [x];
        t [x] = father;
        x = T;
    }
    return father;
}

void unite (const int &x, const int &y) {
    int i;
    if (h [y] > h [x])
        t [x] = y;
    else
        t [y] = x;
    if (h [x] == h [y])
        h [x] ++;
}

void apm () {
    int i;

    sort (E + 1, E + 1 + m, MyComp ());
    for (i = 1; i <= n; i ++) {
        t [i] = i;
        h [i] = 1;
    }
    for (i = 1; i <= m && u < n - 1; i ++) {
        fx = getFather (E [i].x);
        fy = getFather (E [i].y);
        if (fx != fy) {
            ++ u;
            unite (fx, fy);
            E2 [u] = E [i];
        }
    }
}

void dfs (int x) {
    vector <Edge1> :: iterator it;
    Edge1 node;

    used [x] = 1;
    for (it = graph [x].begin (); it != graph [x].end (); ++ it)  {
        node = *it;
        if (!used [node.x]) {
            level [node.x] = level [x] + 1;
            dp [0][node.x] = x;
            dp2 [0][node.x] = node.c;
            dfs (node.x);
        }
    }
}

void makeTree () {
    int i;
    Edge1 node;

    for (i = 1; i <= u; i ++) {
        node.x = E2 [i].y;
        node.c = E2 [i].c;
        graph [E2 [i].x].push_back (node);
        node.x = E2 [i].x;
        graph [E2 [i].y].push_back (node);
    }

    dfs (1);
}

int lca (int x, int y, int &max1, int &max2) {
    int aux, i;

    max1 = -1;
    max2 = -1;
    if (level [y] > level [x]) {
        aux = x;
        x = y;
        y = aux;
    }
    if (level [x] > level [y]) {
        for (i = maxx; i >= 0; i --)
            if (dp [i][x] != 0 && level [dp [i][x]] > level [y]) {
                max1 = max (max1, dp2 [i][x]);
                x = dp [i][x];
            }
         max1 = max (max1, dp2 [0][x]);
        x = dp [0][x];
    }
    if (x == y)
        return x;
    for (i = maxx; i >= 0; i --) {
        if (dp [i][x] && dp [i][y] && dp [i][x] != dp [i][y]) {
            max1 = max (max1, dp2 [i][x]);
            x = dp [i][x];
            max2 = max (max2, dp2 [i][y]);
            y = dp [i][y];
        }
    }
    max1 = max (max1, dp2 [0][x]);
    max2 = max (max2, dp2 [0][y]);
    return dp [0][x];
}

int main () {
    int  k, xx, yy, cc,  i, j, max1, max2, ans;

    freopen ("radiatie.in", "r", stdin);
    freopen ("radiatie.out", "w", stdout);

    scanf ("%d%d%d", &n, &m, &k);
    for (i = 1; i <= m; i ++) {
        scanf ("%d%d%d", &xx, &yy, &cc);
        E [i].x = xx;
        E [i].y = yy;
        E [i].c = cc;
    }
    apm ();
    makeTree ();

    for (i = 1; (1 << i) <= n; i ++) {
        maxx = i;
        for (j = 1; j <= n; j ++) {
            dp [i][j] = dp [i - 1][dp [i - 1][j]];
            dp2 [i][j] = max (dp2 [i - 1][j], dp2 [i - 1][dp [i - 1][j]]);
        }
    }

    for (i = 1; i <= k; i ++) {
        scanf ("%d%d", &xx, &yy);
        cc = lca (xx, yy, max1, max2);
        ans = max (max1, max2);
        printf ("%d\n", ans);
    }
    return 0;
}