Cod sursa(job #1147837)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 20 martie 2014 10:40:06
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

#define NMAX 16007
#define LMAX 17

using namespace std;

struct apm{
    int x;
    int y;
    int c;
    bool operator < (const apm &x) const{
        return c < x.c;
    }
};

vector< apm > a;
vector< pair< int, int > > v[NMAX];
vector< int > Sol;
int T[NMAX], H[NMAX], Cost[NMAX], Viz[NMAX], D[LMAX][NMAX], Level[NMAX], Mat[LMAX][NMAX];
int n, m, k;

inline apm make_apm(int _x, int _y, int _c){
    apm a;
    a.x = _x;
    a.y = _y;
    a.c = _c;
    return a;
}

inline int father(int _x){
    if(_x == T[_x])
        return _x;
    return father(T[_x]);
}

inline void unite(int _x, int _y, int c){
    if(H[_x] < H[_y])
        T[_x] = _y;
    else
        if(H[_x] > H[_y])
            T[_y] = _x;
        else{
            T[_y] = _x;
            ++H[_x];
        }
}

void Fa_Apm(){
    sort(a.begin(), a.end());
    int Nr = 0;
    for(int i = 1; i <= n; ++i){
        T[i] = i;
        H[i] = 1;
    }
    for(vector< apm >::iterator it = a.begin(); it != a.end(); ++it){
        int Tx = father(it->x);
        int Ty = father(it->y);
        if(Tx != Ty){
            unite(Tx, Ty, it->c);
            Sol.push_back(Nr);
        }
        ++Nr;
    }
}

void Dfs_Level(int Nod, int dad, int Cost) {
    D[0][Nod] = dad;
    Level[Nod] = Level[dad] + 1;
    Mat[0][Nod] = Cost;
    for(vector< pair< int, int > >::iterator it = v[Nod].begin(); it != v[Nod].end(); ++ it)
        if(it->first != dad)
            Dfs_Level(it->first, Nod, it->second);
}

void make_new_graph(){
    for(vector< int >::iterator it = Sol.begin(); it != Sol.end(); ++it)
        v[a[*it].x].push_back(make_pair(a[*it].y, a[*it].c));
}

void Dinamica_stramosi(){
    for(int i = 1; (1 << i) <= n; ++i)
        for(int j = 1; j <= n; ++j){
            D[i][j] = D[i - 1][D[i - 1][j]];
            Mat[i][j] = max(Mat[i - 1][j], Mat[i - 1][D[i - 1][j]]);
        }
}

inline int LCA(int a, int b){
    int Max = 0;
    if(Level[a] < Level[b])
        swap(a, b);
    for(int i = LMAX - 1; i >= 0; --i)
        if(Level[a] - (1 << i) >= Level[b]){
            Max = max(Max, Mat[i][a]);
            a = D[i][a];
        }
    if(a == b)
        return Max;
    for(int i = LMAX - 1; i >= 0; --i)
        if(D[i][a] != D[i][b]){
            Max = max(Max, Mat[i][a]);
            Max = max(Max, Mat[i][b]);
            a = D[i][a];
            b = D[i][b];
        }
    Max = max(Max, Mat[0][a]);
    Max = max(Max, Mat[0][b]);
    return Max;
}

inline int query(int a, int b){
    return LCA(a, b);
}

int main(){
    freopen("radiatie.in", "r", stdin);
    freopen("radiatie.out", "w", stdout);
    scanf("%d %d %d", &n, &m, &k);
    for(int i = 1; i <= m; ++i){
        int _a = 0, _b = 0, _c = 0;
        scanf("%d %d %d", &_a, &_b, &_c);
        a.push_back(make_apm(_a, _b, _c));
    }
    Fa_Apm();
    make_new_graph();
    Dfs_Level(1, 1, 0);
    Dinamica_stramosi();
    for(int i = 1; i <= k; ++i){
        int a = 0, b = 0;
        scanf("%d %d", &a, &b);
        printf("%d\n", query(a, b));
    }
    return 0;
}