• 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

  • 相关阅读:
    基于golang+openssh 服务实现一个简单的git over ssh 服务
    dremio 查询sql 执行参考流程
    几款开源git server ssh 协议forced command 参考格式
    dremio job 处理流程参考
    基于golang cgi 实现一个简单的git http server
    dremio cloud 分层datasets 实践
    flightsql apache arrow sql 扩展
    Docker 三剑客之 Docker Swarm
    查看docker服务状态
    SQL去重的三种方法汇总​
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4577087.html
Copyright © 2020-2023  润新知