zoukankan      html  css  js  c++  java
  • USACO15DEC最大流MaxFlow

    传送门

    这是个假的最大流,其实是一个用树剖+线段树就能解决的事情

    题目中的道路会对路径上的造成压力,最后询问最大的压力

    其实就等价于对每条路径上的点加上 1 的权值,并且最后询问整个树中的最大值

    然后树剖+最大值线段树裸题,完事,莫得别的问题了.

    (Updated:)
    其实,可以树上差分+遍历解决的吧...当时好像有点学数据结构学傻了

    Code:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #define ls ( rt << 1 )
    #define rs ( rt << 1 | 1 )
    #define mid ( ( l + r ) >> 1 )
    #define pushup(rt) t[rt].data = max ( t[ls].data , t[rs].data )
    
    using std::vector ;
    using std::max ;
    
    const int N = 1e5 + 5 ;
    
    struct seg {
        int left , right , data , tag ;
        inline int size () { return right - left + 1 ; }
    }t[(N<<2)] ;
    
    vector < int > G[N] ;
    int n , k , val[N] , son[N] , idx[N] , ans ;
    int tot , deep[N] , f[N] , siz[N] , top[N] ;
    
    inline void dfs ( int cur , int anc , int dep ) {
        f[cur] = anc ; deep[cur] = dep ; siz[cur] = 1 ;
        int maxson = - 1 ; for ( int k : G[cur] ) {
            if ( k == anc ) continue ;
            dfs ( k , cur , dep + 1 ) ; siz[cur] += siz[k] ;
            if ( siz[k] > maxson ) maxson = siz[k] , son[cur] = k ;
        }
        return ;
    }
    
    inline void _dfs ( int cur , int topf ) {
        top[cur] = topf ; idx[cur] = ++ tot ; val[tot] = 0 ;
        if ( ! son[cur] ) return ; _dfs ( son[cur] , topf ) ;
        for ( int k : G[cur] ) {
            if ( k == f[cur] || k == son[cur] ) continue ;
            _dfs ( k , k ) ;
        }
        return ;
    }
    
    inline void build ( int rt , int l , int r ) {
        t[rt].left = l ; t[rt].right = r ; t[rt].tag = 0 ;
        if ( l == r ) { t[rt].data = val[l] ; return ; }
        build ( ls , l , mid ) ; build ( rs , mid + 1 , r ) ;
        pushup ( rt ) ; return ;
    }
    
    inline void pushdown ( int rt ) {
        t[ls].tag += t[rt].tag ; t[rs].tag += t[rt].tag ;
        t[ls].data += t[rt].tag ; t[rs].data += t[rt].tag ;
        t[rt].tag = 0 ; return ;
    }
    
    inline void update ( int rt , int ll , int rr , int key ) {
        int l = t[rt].left , r = t[rt].right ;
        if ( ll <= l && r <= rr ) {
            t[rt].tag += key ;
            t[rt].data += key ;
            return ;
        }
        if ( t[rt].tag != 0 ) pushdown ( rt ) ;
        if ( ll <= mid ) update ( ls , ll , rr , key ) ;
        if ( rr > mid ) update ( rs , ll , rr , key ) ;
        pushup ( rt ) ; return ;
    }
    
    inline void query ( int rt , int ll , int rr ) {
        int l = t[rt].left , r = t[rt].right ;
        if ( ll <= l && r <= rr ) {
            ans = max ( ans , t[rt].data ) ;
            return ;
        }
        if ( t[rt].tag != 0 ) pushdown ( rt ) ;
        if ( ll <= mid ) query ( ls , ll , rr ) ;
        if ( rr > mid ) query ( rs , ll , rr ) ;
        return ;
    }
    
    inline void uprange (int x , int y , int key) {
        while ( top[x] != top[y] ) {
            if ( deep[top[x]] < deep[top[y]] ) std::swap ( x , y ) ;
            update ( 1 , idx[top[x]] , idx[x] , key ) ; x = f[top[x]] ;
        }
        if ( deep[x] > deep[y] ) std::swap ( x , y ) ;
        update ( 1 , idx[x] , idx[y] , key ) ; return ;
    }
    
    int main () {
        scanf ("%d%d" , & n , & k ) ;
        for (int i = 1 ; i < n ; ++ i) {
            register int u , v ;
            scanf ("%d%d" , & u , & v ) ;
            G[u].push_back ( v ) ;
            G[v].push_back ( u ) ;
        }
        dfs ( 1 , 0 , 1 ) ; _dfs ( 1 , 1 ) ; build ( 1 , 1 , tot ) ;
        while ( k -- ) {
            register int u , v ;
            scanf ("%d%d" , & u , & v ) ;
            uprange ( u , v , 1 ) ;
        }
        ans = - 1 ; query ( 1 , idx[1] , idx[1] + siz[1] - 1 ) ;
        printf ("%d
    " , ans ) ; system ("pause") ; return 0 ;
    }
    
    May you return with a young heart after years of fighting.
  • 相关阅读:
    开发中学习英语
    eclipse 常用快捷键
    eclipse 查看快捷键
    沟通的方式——大道至简第四章读后感
    java练习题——类与对象
    团队与管理方法——大道至简第三章读后感
    java程序——两数的加减乘除
    java练习题
    java程序——从命令行接收多个数字,求和之后输出结果
    李冰烧山——大道至简第二章读后感
  • 原文地址:https://www.cnblogs.com/Equinox-Flower/p/10785248.html
Copyright © 2011-2022 走看看