Cod sursa(job #1146509)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 19 martie 2014 07:33:41
Problema Radiatie Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#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< int > Sol, v[NMAX];
int T[NMAX], H[NMAX], Cost[NMAX], Viz[NMAX], D[LMAX][NMAX], Level[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;
        Cost[_x] = c;
    }
    else
        if(H[_x] > H[_y]){
            T[_y] = _x;
            Cost[_y] = c;
        }
        else{
            T[_y] = _x;
            Cost[_x] = c;
            ++H[_x];
        }
}

void Fa_Apm(){
    sort(a.begin(), a.end());
    int Nr = 0;
    for(int i = 0; i < a.size(); ++i)
        T[i + 1] = 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 Lev){
    Level[Nod] = Lev;
    Viz[Nod] = 1;
    for(vector< int >::iterator it = v[Nod].begin(); it != v[Nod].end(); ++it)
        if(Viz[*it] == 0){
            D[0][*it] = Nod;
            Dfs_level(*it, Lev + 1);
        }
}

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

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]];
}

inline int LCA(int a, int b){
    int Max = 0;
    if(Level[a] < Level[b])
        swap(a, b);
    Max = max(Cost[a], Cost[b]);
    for(int i = LMAX - 1; i >= 0; --i)
        if(Level[a] - (1 << i) <= Level[b]){
            a = D[i][a];
            Max = max(Max, Cost[a]);
        }
    if(a == b)
        return a;
    for(int i = LMAX - 1; i >= 1; --i)
        if(D[i][a] && D[i][a] != D[i][b]){
            a = D[i][a];
            b = D[i][b];
            Max = max(Max, Cost[a]);
            Max = max(Max, Cost[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);
    Dinamica_stramosi();
    /// pt fiecare query
    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;
}