Cod sursa(job #977854)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 26 iulie 2013 21:46:27
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int MAX_N = 15002;
const int MAX_M = 32002;

typedef struct edge {
    int x, y, c;
};

int N, M, K, Nr;
int E[MAX_N*2], d[MAX_N*2], F[MAX_N], H[MAX_N], level[MAX_N], pos[MAX_N], dp[16][MAX_N], T[16][MAX_N], A[MAX_N][16], P[MAX_N][16], log2[MAX_N];
vector < pair < int, int > > v[MAX_N];
bool m[MAX_N];
edge w[MAX_M];

inline bool cmp(edge a, edge b) {
    return a.c < b.c;
}

inline void DFS(int x, int lv) {
    E[++Nr] = x, d[Nr] = lv, level[x] = lv, m[x] = 1, pos[x] = Nr;
    for(size_t i = 0; i < v[x].size(); ++i) {
        int y = v[x][i].first, c = v[x][i].second;
        if(!m[y])
            T[0][y] = x, dp[0][y] = c, DFS(y, lv+1);
    }
}

inline void RMQ() {
    for(int i = 1; i <= Nr; ++i)
        A[i][0] = d[i], P[i][0] = i;
    for(int j = 1; (1 << j) <= Nr; ++j)
        for(int i = 1; i + (1 << j) - 1 <= Nr; ++j)
            if(A[i][j-1] < A[i + (1 << (j-1))][j-1])
                A[i][j] = A[i][j-1], P[i][j] = P[i][j-1];
            else A[i][j] = A[i + (1 << (j-1))][j-1], P[i][j] = P[i + (1 << (j-1))][j-1];
}

inline int LCA(int x, int y) {
    x = pos[x], y = pos[y];
    if(x > y)
        swap(x, y);
    int k = log2[x-y+1], t = 0;
    if(A[x][k] < A[y-k+1][k])
        t = P[x][k];
    else t = P[y-k+1][k];
    return pos[t];
}

inline int Max_dist(int x, int k) {
    int ans = 0;
    while(k) {
        int t = log2[k];
        ans = max(ans, dp[t][x]);
        x = T[t][x];
        k -= (1 << t);
    }
    return ans;
}

inline int Query(int x, int y) {
    int z = LCA(x, y);
    return max(Max_dist(x, level[x] - level[z]), Max_dist(y, level[y] - level[z]));
}

inline int find(int x) {
    int R = x;
    while(R != F[R])
        R = F[R];
    while(x != F[x]) {
        int temp = F[x];
        F[x] = R;
        x = temp;
    }
    return R;
}

inline void unite(int x, int y) {
    if(H[x] > H[y])
        F[y] = x;
    else F[x] = y;
    if(H[x] == H[y])
        ++H[y];
}


int main() {
    ifstream f("radiatie.in");
    ofstream g("radiatie.out");

    f >> N >> M >> K;
    for(int i = 1; i <= M; ++i)
        f >> w[i].x >> w[i].y >> w[i].c;

    for(int i = 1; i <= N; ++i)
        F[i] = i, H[i] = 1;
    for(int i = 2; i <= N; ++i)
        log2[i] = log2[i/2] + 1;
    sort(w+1, w+N+1, cmp);
    for(int i = 1, k = 1; i <= M, k < N; ++i)
        if(find(w[i].x) != find(w[i].y))
            w[k++] = w[i], unite(find(w[i].x), find(w[i].y));
    for(int i = 1; i < N; ++i) {
        v[w[i].x].push_back(make_pair(w[i].y, w[i].c));
        v[w[i].y].push_back(make_pair(w[i].x, w[i].c));
    }

    DFS(1, 0);
    for(int j = 1; (1 << j) <= N; ++j)
        for(int i = 1; i <= N; ++i)
            if(dp[j-1][i] > dp[j-1][T[j-1][i]]) {
                dp[j][i] = dp[j-1][i];
                T[j][i] = T[j-1][i];
            }
            else {
                dp[j][i] = dp[j-1][T[j-1][i]];
                T[j][i] = T[j-1][T[j-1][i]];
            }
    RMQ();

    for(int i = 1, x, y; i <= K; ++i) {
        f >> x >> y;
        g << Query(x, y) << "\n";
    }

    f.close();
    g.close();

    return 0;
}