Cod sursa(job #1513499)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 29 octombrie 2015 17:17:06
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <tuple>

using namespace std;

ifstream in("radiatie.in");
ofstream out("radiatie.out");

const int MAX_N = 15000;
const int MAX_M = 30000;
const int MAX_LOG = 13;

struct Edge {
    int u;
    int v;
    int c;
};

int n, m, k;
int H[1 + MAX_N];
int Anc[1 + MAX_N][MAX_LOG], D[1 + MAX_N][MAX_LOG];
int uRank[1 + MAX_N], uParent[1 + MAX_N];
vector < pair <int, int> > A[1 + MAX_N];
Edge E[1 + MAX_M];

int getRoot(int u) {
    if(u != uParent[u])
        uParent[u] = getRoot(uParent[u]);
    return uParent[u];
}

bool uTest(int u, int v) {
    return getRoot(u) == getRoot(v);
}

void uMerge(int u, int v) {
    int rU = getRoot(u), rV = getRoot(v);

    if(uRank[rU] > uRank[rV]) {
        uParent[rV] = rU;
    }
    else if(uRank[rU] < uRank[rV]) {
        uParent[rU] = rV;
    }
    else {
        uParent[rV] = rU;
        uRank[rU]++;
    }
}

bool sortEdge(Edge A, Edge B) {
    return A.c < B.c;
}

void dfs(int u, int u_last) {
    for(auto i : A[u]) {
        if(get<0>(i) != u_last) {
            H[get<0>(i)] = H[u] + 1;
            Anc[get<0>(i)][0] = u;
            D[get<0>(i)][0] = get<1>(i);
            dfs(get<0>(i), u);
        }
    }
}

int getAnc(int u, int k) {
    int i, anc = u;
    for(i = 0; (1 << i) <= k; i++) {
        if(k & (1 << i)) {
            anc = Anc[anc][i];
        }
    }
    return anc;
}

int getLCA(int u, int v) {
    int i, l = 1, r = min(H[u], H[v]), mid, lastF = -1;

    while(l <= r) {
        mid = (l + r) / 2;
        if(getAnc(u, H[u] - mid) == getAnc(v, H[v] - mid)) {
            l = mid + 1;
            lastF = mid;
        }
        else {
            r = mid - 1;
        }
    }

    return getAnc(u, H[u] - lastF
                  );
}

/*int getLCA(int u, int v) {
    int i;

    if(H[u] < H[v]) swap(u, v);
    u = getAnc(u, H[u] - H[v]);

    if(u == v) return u;

    for(i = 0; (1 << i) <= H[u]; i++);
    for(--i; i >= 0; i--) {
        if(Anc[u][i] > 0 && Anc[u][i] != Anc[v][i]) {
            u = Anc[u][i];
            v = Anc[v][i];
        }
    }

    return H[Anc[u][0]];
}*/

int getQuery(int u, int k) {
    int ans = 0, i, anc = u;
    for(i = 0; (1 << i) <= k; i++) {
        if(k & (1 << i)) {
            ans = max(ans, D[anc][i]);
            anc = Anc[anc][i];
        }
    }
    return ans;
}




int main() {
    int i, j, eLeft, u, v, w;

    in >> n >> m >> k;
    for(i = 1; i <= m; i++) {
        in >> E[i].u >> E[i].v >> E[i].c;
    }

    for(i = 1; i <= n; i++) {
        uParent[i] = i;
        uRank[i] = 1;
    }

    sort(E + 1, E + m + 1, sortEdge);
    for(i = 1, eLeft = n - 1; i <= m && eLeft; i++) {
        if(uTest(E[i].u, E[i].v) == 0) {
            eLeft--;
            A[E[i].u].push_back(make_pair(E[i].v, E[i].c));
            A[E[i].v].push_back(make_pair(E[i].u, E[i].c));
            uMerge(E[i].u, E[i].v);
        }
    }

    H[1] = 1;
    dfs(1, 0);

    for(i = 1; (1 << i) <= n; i++) {
        for(j = 1; j <= n; j++) {
            Anc[j][i] = Anc[Anc[j][i-1]][i-1];
            D[j][i] = max(D[j][i-1], D[Anc[j][i-1]][i-1]);
        }
    }

    for(i = 1; i <= k; i++) {
        in >> u >> v;
        w = getLCA(u, v);
        out << max(getQuery(u, H[u] - w), getQuery(v, H[v] - w)) << '\n';
    }

    return 0;
}