Cod sursa(job #1667082)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 28 martie 2016 17:23:27
Problema Radiatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.87 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<bitset>

using namespace std;

FILE *fin = fopen( "radiatie.in", "r" ), *fout = fopen( "radiatie.out", "w" );

typedef vector< pair< int, int > > graf;

const int nmax = 15 * 1e3;
const int lgmax = 13;
const int Size = 8 * 1e6;
int buffpos;
char buff[ Size ];

int n;
int tata[ nmax + 1 ], ad[ nmax + 1 ];

bitset< nmax + 1 > viz;
pair< int, int > d[ lgmax + 1 ][ nmax + 1 ];

int h[ nmax + 1 ];
graf g[ nmax + 1 ];

struct muchie{
    int x, y, c;

    muchie() {}
    muchie( int _x, int _y, int _c ) {
        x = _x, y = _y, c = _c;
    }

    inline bool operator < ( const muchie &a ) const {
        return ( c < a.c );
    }
};
vector< muchie > vm;

inline char nextpos() {
    ++ buffpos;
    if ( buffpos == Size ) {
        buffpos = 0;
        fread( buff, Size, 1, fin );
    }
    return buff[ buffpos ];
}
void getnmb( int &x ) {
    char c = nextpos();
    while ( c < '0' || c > '9' ) {
        c = nextpos();
    }
    x = 0;
    while ( c >= '0' && c <= '9' ) {
        x = x * 10 + c - '0';
        c = nextpos();
    }
}
inline int max2( int a, int b ) {
    return ( a < b ? b : a );
}
int find_tata( int x ) {
    if ( x == tata[ x ] ) {
        return x;
    }
    return ( tata[ x ] = find_tata( tata[ x ] ) );
}
void unifica( int x, int y, int c ) {
    int ta = find_tata( x ), tb = find_tata( y );
    if ( ta == tb ) {
        return ;
    }
    g[ x ].push_back( make_pair( y, c ) );
    g[ y ].push_back( make_pair( x, c ) );
    if ( ad[ ta ] < ad[ tb ] ) {
        tata[ ta ] = tb;
    } else if ( ad[ ta ] > ad[ tb ] ) {
        tata[ tb ] = ta;
    } else {
        tata[ tb ] = ta;
        ++ ad[ ta ];
    }
}
void apm() {
    sort( vm.begin(), vm.end() );
    for( int i = 1; i <= n; ++ i ) {
        tata[ i ] = i;
        ad[ i ] = 0;
    }
    for( vector< muchie >::iterator it = vm.begin(); it != vm.end(); ++ it ) {
        unifica( it -> x, it -> y, it -> c );
    }
}
void dfs( int nod ) {
    viz[ nod ] = 1;
    for( graf::iterator it = g[ nod ].begin(); it != g[ nod ].end(); ++ it ) {
        if ( viz[ it -> first ] == 0 ) {
            d[ 0 ][ it -> first ] = make_pair( nod, it -> second );
            h[ it -> first ] = h[ nod ] + 1;
            dfs( it -> first );
        }
    }
}
void calc_dinamica() {
    for( int i = 1; i <= lgmax; ++ i ) {
        for( int j = 1; j <= n; ++ j ) {
            int x = d[ i - 1 ][ j ].first;
            d[ i ][ j ].first = d[ i - 1 ][ x ].first;
            d[ i ][ j ].second = max2( d[ i - 1 ][ j ].second, d[ i - 1 ][ x ].second );
        }
    }
}
int solve( int x, int y ) {
    int ans = 0;
    if ( h[ x ] < h[ y ] ) {
        x ^= y ^= x ^= y;
    }
    int dif = h[ x ] - h[ y ];
    for( int step = lgmax; step >= 0; -- step ) {
        if ( dif & (1 << step) ) {
            ans = max2( ans, d[ step ][ x ].second );
            x = d[ step ][ x ].first;
        }
    }
    for( int step = lgmax; step >= 0; -- step ) {
        if ( d[ step ][ x ].first != d[ step ][ y ].first ) {
            ans = max2( ans, d[ step ][ x ].second );
            ans = max2( ans, d[ step ][ y ].second );
            x = d[ step ][ x ].first;
            y = d[ step ][ y ].first;
        }
    }
    if ( x != y ) {
        ans = max2( ans, d[ 0 ][ x ].second );
        ans = max2( ans, d[ 0 ][ y ].second );
    }
    return ans;
}
int main() {
    int m, k;
    buffpos = Size - 1;

    getnmb( n ); getnmb( m ); getnmb( k );
    for( int i = 0; i < m; ++ i ) {
        int x, y, c;
        getnmb( x ); getnmb( y ); getnmb( c );
        vm.push_back( muchie( x, y, c ) );
    }

    apm();
    for( int i = 1; i <= n; ++ i ) {
        if ( viz[ i ] == 0 ) {
            dfs( i );
        }
    }
    calc_dinamica();

    while ( k -- ) {
        int x, y;
        getnmb( x ); getnmb( y );
        fprintf( fout, "%d\n", solve( x, y ) );
    }

    fclose( fin );
    fclose( fout );
    return 0;
}