zoukankan      html  css  js  c++  java
  • BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )

    这道题用 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 " , 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

  • 相关阅读:
    Asp.net的一些编码问题
    计算ScriptResource.axd的d参数
    关于控件Visible属性的说明
    多分类产品查询
    广告位管理系统跨域广告加载问题
    广告位管理系统使用说明
    Repeater控件备忘
    SubSonic中的字段付值MakeOld & Update
    关于Left join 到 Inner join 的提升MSSQL自动转换
    函数(方法)级的授权
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4574766.html
Copyright © 2011-2022 走看看