BZOJ-1433: [ZJOI2009]假期的宿舍(最大流)

作者: AmadeusChan | 来源:发表于2018-10-17 12:25 被阅读1次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1433

    赤赤裸裸的最大流水题,水过去就可以啦。

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
     
    using namespace std ;
     
    #define MAXN 10100
    #define AddEdge( s , t , f ) Add( s , t , f ) , Add( t , s , 0 )
    #define inf 0x7fffffff
     
    struct edge {
        int t , f , next ;
    } e[ MAXN ] ;
     
    int head[ MAXN ] , en ;
     
    void Add( int s , int t , int f ) {
        e[ en ].t = t , e[ en ].f = f , e[ en ].next = head[ s ] ;
        head[ s ] = en ++ ;
    }
     
    int node[ MAXN ][ 2 ] , V , S , T ;
    int gap[ MAXN ] , h[ MAXN ] , d[ MAXN ] ;
     
    int sap( int v , int flow ) {
        if ( v == T ) return flow ;
        int rec = 0 ;
        for ( int i = d[ v ] ; i != - 1 ; i = e[ i ].next ) {
            if ( e[ i ].f && h[ v ] == h[ e[ i ].t ] + 1 ) {
                int ret = sap( e[ i ].t , min( flow - rec , e[ i ].f ) ) ;
                e[ i ].f -= ret , e[ i ^ 1 ].f += ret , d[ v ] = i ;
                if ( ( rec += ret ) == flow ) return flow ;
            }
        }
        if ( ! ( -- gap[ h[ v ] ] ) ) h[ S ] = T ;
        gap[ ++ h[ v ] ] ++ , d[ v ] = head[ v ] ;
        return rec ;
    }
     
    int maxflow(  ) {
        memset( gap , 0 , sizeof( gap ) ) ; 
        memset( h , 0 , sizeof( h ) ) ;
        for ( int i = 0 ; i ++ < T ; ) d[ i ] = head[ i ] ;
        gap[ 0 ] = T ;
        int flow = 0 ;
        while ( h[ S ] < T ) flow += sap( S , inf ) ;
        return flow ;
    }
     
    int a[ MAXN ] , b[ MAXN ] , n , tot ;
     
    int main(  ) {
        scanf( "%d" , &tot ) ;
        while ( tot -- ) {
            int cnt = 0 ;
            en = V = 0 ; 
            scanf( "%d" , &n ) ;
            for ( int i = 0 ; i ++ < n ; ) {
                node[ i ][ 0 ] = ++ V , node[ i ][ 1 ] = ++ V ;
            }
            S = ++ V ; T = ++ V ;
            for ( int i = 0 ; i ++ < V ; ) head[ i ] = - 1 ;
            for ( int i = 0 ; i ++ < n ; ) scanf( "%d" , a + i ) ;
            for ( int i = 0 ; i ++ < n ; ) scanf( "%d" , b + i ) ;
            for ( int i = 0 ; i ++ < n ; ) {
                if ( a[ i ] ) AddEdge( node[ i ][ 1 ] , T , 1 ) ;
                if ( ! ( a[ i ] && b[ i ] ) ) AddEdge( S , node[ i ][ 0 ] , 1 ) , ++ cnt ;
                AddEdge( node[ i ][ 0 ] , node[ i ][ 1 ] , 1 ) ;
            }
            for ( int i = 0 ; i ++ < n ; ) {
                for ( int j = 0 ; j ++ < n ; ) {
                    int x ; scanf( "%d" , &x ) ;
                    if ( x ) AddEdge( node[ i ][ 0 ] , node[ j ][ 1 ] , 1 ) ;
                }
            }
            printf( maxflow(  ) == cnt ? "^_^\n" : "T_T\n" )  ;
        }
        return 0 ;
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-1433: [ZJOI2009]假期的宿舍(最大流)

        本文链接:https://www.haomeiwen.com/subject/cfnlzftx.html