• BZOJ 1576: [Usaco2009 Jan]安全路经Travel( 树链剖分 )


    树链剖分...略麻烦... 

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #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 )
    #define L( x ) ( ( x ) << 1 )
    #define R( x ) ( L( x ) ^ 1 )
    #define M( l , r ) ( ( l + r ) >> 1 )
    #define LC L( x ) , l , m
    #define RC R( x ) , m + 1 , r
    #define X x , l , r
    #define XX int x , int l , int r
    #define all 1 , 1 , n
     
    using namespace std;
     
    const int inf = 0x3f3f3f3f;
    const int maxm = 200000 + 5;
    const int maxn = 100000 + 5;
    const int maxnode = 270000;
     
    int n;
     
    struct edge {
    int to , dist;
    bool is;
    edge* next;
    edge() {
    is = false;
    }
    };
     
    edge* pt , EDGE[ maxm << 1 ];
    edge* head[ maxn ];
     
    void edge_init() {
    pt = EDGE;
    clr( head , 0 );
    }
     
    void add( int u , int v , int d ) {
    pt -> to = v;
    pt -> dist = d;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
    #define add_edge( u , v , d )  add( u , v , d ) , add( v , u , d )
     
    struct node {
    int x , d;
    bool operator < ( const node &o ) const {
    return d > o.d;
    }
    };
     
    priority_queue< node > Q;
    int d[ maxn ];
     
    void dijkstra() {
    clr( d , inf );
    d[ 0 ] = 0;
    Q.push( ( node ) { 0 , 0 } );
    while( ! Q.empty() ) {
    node o = Q.top();
    Q.pop();
    int x = o.x , dist = o.d;
    if( d[ x ] != dist ) continue;
    REP( x ) {
    int to = e -> to;
    if( d[ to ] > dist + e -> dist ) {
    d[ to ] = dist + e -> dist;
    Q.push( ( node ) { to , d[ to ] } );
    }
    }
    }
    }
     
    void build_tree() {
    rep( x , n ) {
    int dist = d[ x ];
       REP( x ) {
        int to = e -> to;
        if( e -> dist + d[ x ] == d[ to ] )
           e -> is = true;
       }
    }
    }
     
    int top[ maxn ] , id[ maxn ] , son[ maxn ] , fa[ maxn ], id_cnt = 0;
    int size[ maxn ] , dep[ maxn ];
     
    void dfs( int x ) {
    size[ x ] = 1;
    son[ x ] = -1;
    REP( x ) {
    int to = e -> to;
    if( to == fa[ x ] || ! e -> is ) continue;
    fa[ to ] = x;
    dep[ to ] = dep[ x ] + 1;
    dfs( to );
    size[ x ] += size[ to ];
    if( son[ x ] == -1 || size[ to ] > size[ son[ x ] ] )
       son[ x ] = to;
    }
    }
     
    int TOP;
    void DFS( int x ) {
    top[ x ] = TOP;
    id[ x ] = ++id_cnt;
    if( son[ x ] != -1 ) DFS( son[ x ] );
    REP( x ) if( id[ e -> to ] == -1 && e -> is ) 
       DFS( TOP = e -> to );
    }
     
    void DFS_init() {
    clr( id , -1 );
    dfs( dep[ 0 ] = 0 );
    DFS( TOP = 0 );
    }
     
    int set[ maxnode ] , val[ maxnode ];
    int L , R , v;
     
    void pushdown( XX ) {
    if( set[ x ] != inf && r > l ) {
    set[ L( x ) ] = min( set[ L( x ) ] , set[ x ] );
    set[ R( x ) ] = min( set[ R( x ) ] , set[ x ] );
    set[ x ] = inf;
    }
    }
     
    void maintain( XX ) {
    if( set[ x ] != inf )
    val[ x ] = min( val[ x ] , set[ x ] );
    }
     
    void update( XX ) {
    if( L <= l && r <= R ) {
    set[ x ] = min( set[ x ] , v );
    } else {
    int m = M( l , r );
    pushdown( X );
    L <= m ? update( LC ) : maintain( LC );
    m < R ? update( RC ) : maintain( RC );
    }
    maintain( X );
    }
     
    int query( XX ) {
    if( l == r ) 
       return val[ x ];
    int m = M( l , r );
    pushdown( X );
    maintain( LC );
    maintain( RC );
    return L <= m ? query( LC ) : query( RC );
    }
     
    int query_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;
    }
    void modify( int x , int y , int d ) {
    v = d;
    while( top[ x ] != top[ y ] ) {
    if( dep[ top[ x ] ] < dep[ top[ y ] ] ) 
       swap( x , y );
    L = id[ top[ x ] ] , R = id[ x ];
    update( all );
    x = fa[ top[ x ] ];
    }
    if( x != y ) {
    if( dep[ x ] < dep[ y ] ) 
       swap( x , y );
    L = id[ y ] + 1 , R = id[ x ];
    update( all );
    }
    }
     
    void work() {
    rep( x , n ) {
    REP( x ) if( ! e -> is ) {
    int lca = query_LCA( x , e -> to );
       modify( lca , e -> to , d[ x ] + d[ e -> to ] + e -> dist );
    }
    }
    }
     
    inline int read() {
    char c = getchar();
    int res = 0;
    while( ! isdigit( c ) ) c = getchar();
    while( isdigit( c ) ) {
    res = res * 10 + c - '0';
    c = getchar();
    }
    return res;
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    n = read();
    int m = read();
    edge_init();
    while( m-- ) {
    int u = read() , v = read() , d = read();
    u-- , v--;
    add_edge( u , v , d );
    }
    dijkstra();
    build_tree();
    DFS_init();
    clr( set , inf );
    clr( val , inf );
    work();
    for( int i = 1 ; i < n ; ++i ) {
    L = id[ i ];
    int res = query( all );
    if( res != inf ) {
    printf( "%d " , res - d[ i ] );
    } else 
       printf( "-1 " );
    }
    return 0;
    }

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

    1576: [Usaco2009 Jan]安全路经Travel

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 740  Solved: 254
    [Submit][Status][Discuss]

    Description

    Input

    * 第一行: 两个空格分开的数, N和M

    * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i

    Output

    * 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.

    Sample Input

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

    输入解释:

    跟题中例子相同

    Sample Output

    3
    3
    6

    输出解释:

    跟题中例子相同

    HINT

    Source

  • 相关阅读:
    字符串及课堂例子整理
    大道至简:软件工程实践者的思想——第四章感想
    大道至简:软件工程实践者的思想——第一章感想(重写)
    大道至简:软件工程实践者的思想——第三章感想
    大道至简:软件工程实践者的思想——第二章感想和课后思考
    简单程序代码及心得体会
    《大 道 至 简   ——软件工程实践者的思想 》是懒人造就了方法读后感
    实验报告
    懒人的思考造就了方法
    编程其实很简单
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4577087.html
Copyright © 2020-2023  润新知