# 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 ;
}
CodeForces - 827D [Best Edge Weight] 倍增+最小生成树+并查集
最新推荐文章于 2020-08-26 20:23:39 发布