您的位置:首页 > 其它

BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )

2015-06-14 11:00 253 查看


这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分...

其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像= = #9

----------------------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; i++ )#define clr( x , c ) memset( x , c , sizeof( x ) )#define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next ) using namespace std; const int maxn = 500000 + 5; struct edge { int to; edge* next;}; edge* pt , EDGE[ maxn << 1 ];edge* head[ maxn ]; void edge_init() { pt = EDGE; clr( head , 0 );} void add( int u , int v ) { pt -> to = v; pt -> next = head[ u ]; head[ u ] = pt++;}#define add_edge( u , v ) add( u , v ) , add( v , u ) int fa[ maxn ] , top[ maxn ] , size[ maxn ] , son[ maxn ] , dep[ maxn ];int id[ maxn ] , _id[ maxn ] , id_cnt = 0 , TOP; void dfs( int x ) { size[ x ] = 1; son[ x ] = -1; REP( x ) { int to = e -> to; if( to == fa[ x ] ) continue; dep[ to ] = dep[ x ] + 1; fa[ to ] = x; dfs( to ); size[ x ] += size[ to ]; if( son[ x ] == - 1 || size[ to ] > size[ son[ x ] ] ) son[ x ] = to; }} void DFS( int x ) { top[ x ] = TOP; id[ x ] = ++id_cnt; _id[ id_cnt ] = x; if( son[ x ] != -1 ) DFS( son[ x ] ); REP( x ) if( id[ e -> to ] < 0 ) DFS( TOP = e -> to );} void DFS_init() { clr( id , -1 ); dfs( dep[ 0 ] = 0 ); DFS( TOP = 0 );} int Q_LCA( int x , int y ) { while( top[ x ] != top[ y ] ) { if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y ); x = fa[ top[ x ] ]; } return dep[ x ] < dep[ y ] ? x : y;} int Q_dist( int x , int y ) { int res = 0; while( top[ x ] != top[ y ] ) { if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y ); res += id[ x ] - id[ top[ x ] ]; x = fa[ top[ x ] ]; res++; } if( dep[ x ] < dep[ y ] ) swap( x , y ); return res + id[ x ] - id[ y ];} int ans[ 2 ];void work( int x , int y , int z ) { int LCA[ 3 ] = { Q_LCA( x , y ) , Q_LCA( x , z ) , Q_LCA( y , z ) }; if( LCA[ 0 ] == LCA[ 1 ] ) ans[ 0 ] = LCA[ 2 ]; else if( LCA[ 0 ] == LCA[ 2 ] ) ans[ 0 ] = LCA[ 1 ]; else ans[ 0 ] = LCA[ 0 ]; ans[ 1 ] = Q_dist( x , ans[ 0 ] ) + Q_dist( y , ans[ 0 ] ) + Q_dist( z , ans[ 0 ] );} inline int read() { int res = 0; char c = getchar(); while( ! isdigit( c ) ) c = getchar(); while( isdigit( c ) ) { res = res * 10 + c - '0'; c = getchar(); } return res;} int main() { freopen( "test.in" , "r" , stdin ); int n = read() , m = read(); edge_init(); rep( i , n - 1 ) { int u = read() , v = read(); u-- , v--; add_edge( u , v ); } DFS_init(); while( m-- ) { int x = read() , y = read() , z = read(); x-- , y-- , z--; work( x , y , z ); printf( "%d %d\n" , ans[ 0 ] + 1 , ans[ 1 ] ); } return 0;}

----------------------------------------------------------------------------------

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec Memory Limit: 162 MB
Submit: 1542 Solved: 683
[Submit][Status][Discuss]

Description


Input


Output


Sample Input

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

Sample Output

5 2
2 5
4 1
6 0

HINT



Source

Day1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: