1. 程式人生 > >827D [Best Edge Weight] 倍增+最小生成樹+並查集

827D [Best Edge Weight] 倍增+最小生成樹+並查集

# include <vector>
# include <cstdio>
# include <cstring>
# include <iostream>
# include <algorithm>
# define Name "weight"

using namespace std ;

inline int Read () {
    int x = 0 , f = 1 ;
    char ch = getchar () ;
    while ( ! isdigit ( ch ) ) {
        if ( ch == '-'
) f = - 1; ch = getchar () ; } while ( isdigit ( ch ) ) { x = x * 10 + ch - '0' ; ch = getchar () ; } return x * f ; } const int N = 2e5 + 10 ; const int Inf = 0x3f3f3f3f ; struct Edge { int id ; int u , v , w ; Edge ( int x = 0 , int y = 0 , int z = 0 ) : v ( x ) , w ( y ) , id ( z ) {} } e [N] ; vector
<Edge>
edges ; vector <int> G [N] ; int ans [N] , fa [N] [20] , dep [N] , st [N] [20] , used [N] , f [N] , to [N] ; int n , m ; void addeage ( int u , int v , int w , int id ) { edges.push_back ( Edge ( v , w , id ) ) ; int tot = edges.size () ; G [u].push_back ( tot - 1 ) ; } void
dfs ( int u , int fat ) { fa [u] [0] = fat ; for ( int i = 1 ; i <= 18 ; ++ i ) fa [u] [i] = fa [ fa [u] [ i - 1 ] ] [ i - 1 ] , st [u] [i] = max ( st [u] [ i - 1 ] , st [ fa [u] [ i - 1 ] ] [ i - 1 ] ) ; for ( int i = 0 ; i < G [u].size () ; ++ i ) { Edge e = edges [ G [u] [i] ] ; if ( e.v == fat ) continue ; to [e.v] = e.id ; st [e.v] [0] = e.w ; dep [e.v] = dep [u] + 1 ; dfs ( e.v , u ) ; } } int LCA ( int u , int v , int & d ) { d = 0 ; if ( dep [u] < dep [v] ) swap ( u , v ) ; int t = dep [u] - dep [v] ; for ( int i = 0 ; i <= 18 ; ++ i ) if ( ( 1 << i ) & t ) { d = max ( d , st [u] [i] ) ; u = fa [u] [i] ; } if ( u == v ) return u ; for ( int i = 18 ; i >= 0 ; -- i ) { if ( fa [u] [i] != fa [v] [i] ) { d = max ( d , max ( st [u] [i] , st [v] [i] ) ) ; u = fa [u] [i] ; v = fa [v] [i] ; } } d = max ( d , max ( st [u] [0] , st [v] [0] ) ) ; return fa [u] [0] ; } int getfa ( int u ) { return ( u == f [u] ) ? u : f [u] = getfa ( f [u] ) ; } bool cmp ( Edge x , Edge y ) { return x.w < y.w ; } void KrusKal () { int tot = 0 ; sort ( e + 1 , e + 1 + m , cmp ) ; for ( int i = 1 ; i <= m ; ++ i ) { int u = e [i].u , v = e [i].v ; int u1 = getfa ( u ) , v1 = getfa ( v ) ; if ( u1 != v1 ) { f [u1] = v1 ; used [i] = 1 ; addeage ( u , v , e [i].w , e [i].id ) ; addeage ( v , u , e [i].w , e [i].id ) ; tot ++ ; } if ( tot == n - 1 ) break ; } } void modify ( int u , int v , int d ) { u = getfa ( u ) ; while ( dep [u] > dep [v] ) { ans [ to [u] ] = min ( ans [ to [u] ] , d ) ; int y = getfa ( fa [u] [0] ) ; f [u] = y ; u = getfa ( u ) ; } } int main () { // freopen ( Name ".in" , "r" , stdin ) ; scanf ( "%d%d" , & n , & m ) ; for ( int i = 1 ; i <= m ; ++ i ) { int u , v , w ; e [i].u = Read () , e [i].v = Read () , e [i].w = Read () , e [i].id = i ; } for ( int i = 1 ; i <= n ; ++ i ) f [i] = i ; KrusKal () ; dfs ( 1 , 1 ) ; memset ( ans , Inf , sizeof ans ) ; for ( int i = 1 ; i <= n ; ++ i ) f [i] = i ; for ( int i = 1 ; i <= m ; ++ i ) { if ( used [i] ) continue ; int u = e [i].u , v = e [i].v ; int ffa = LCA ( u , v , ans [ e [i].id ] ) ; ans [ e [i].id ] -- ; modify ( u , ffa , e [i].w - 1 ) ; modify ( v , ffa , e [i].w - 1 ) ; } for ( int i = 1 ; i <= m ; ++ i ) if ( ans [i] == Inf ) printf ( "-1 " ) ; else printf ( "%d " , ans [i] ) ; return 0 ; }