网络流24题 洛谷 4015 运输问题

裸体,建图寻常。

#include <bits/stdc++.h>

const  int  N = 500 + 5 ;

std :: queue < int >  q ;

int  head [ N << 8 ] , nxt [ N << 8 ] , flt [ N << 8 ] , dis [ N << 8 ] , to [ N << 8 ] , cn = 1 ;
int  pree [ N ] , pred [ N ] , c [ N ] , inf , src , sink , n , m , maxcost , mincost , ck [ N ] , ls [ N ] ;
int  x [ N ] [ N ] ; 
bool  vis [ N ] ; 

void  create ( int  u , int  v , int  f , int  d ) {
    cn ++ ;
    to [ cn ] = v ;
    dis [ cn ] = d ;
    flt [ cn ] = f ;
    nxt [ cn ] = head [ u ] ;
    head [ u ] = cn ;
    
    cn ++ ;
    to [ cn ] = u ; 
    dis [ cn ] = - d ;
    flt [ cn ] = 0 ;
    nxt [ cn ] = head [ v ] ;
    head [ v ] = cn ; 
} 

void  prp ( ) {
    int  o [ 5 ] ;
    memset ( o , 127 , sizeof ( o ) ) ;
    inf =  o [ 0 ] ;
}

bool  spfa1 ( ) {
    memset ( pree , 0 , sizeof ( pree ) ) ;
    memset ( pred , 0 , sizeof ( pred ) ) ;
    memset ( vis , false , sizeof ( vis ) ) ;
    memset ( c , 127 , sizeof ( c ) ) ;
    q . push ( src ) ;
    c [ src ] = 0 ;
    vis [ src ] = true ;
    while ( ! q . empty ( ) ) {
        int  tmp = q . front ( ) ; q . pop ( ) ;
        vis [ tmp ] = false ;
        for ( int  i = head [ tmp ] ; i ; i = nxt [ i ] ) {
            int  v = to [ i ] ;
            if ( flt [ i ]  &&  c [ v ] > c [ tmp ] + dis [ i ] ) {
                c [ v ] = c [ tmp ] + dis [ i ] ;
                pree [ v ] = i ;
                pred [ v ] = tmp ;
                if ( ! vis [ v ] ) {
                    vis [ v ] = true ;
                    q . push ( v ) ;
                }
            }
        }
    }
    return  c [ sink ] < inf ;
} 

bool  spfa2 ( ) {
    memset ( pree , 0 , sizeof ( pree ) ) ;
    memset ( pred , 0 , sizeof ( pred ) ) ;
    memset ( vis , false , sizeof ( vis ) ) ;
    memset ( c , 128 , sizeof ( c ) ) ;
    q . push ( src ) ;
    c [ src ] = 0 ;
    vis [ src ] = true ;
    while ( ! q . empty ( ) ) {
        int  tmp = q . front ( ) ; q . pop ( ) ;
        vis [ tmp ] = false ;
        for ( int  i = head [ tmp ] ; i ; i = nxt [ i ] ) {
            int  v = to [ i ] ;
            if ( flt [ i ]  &&  c [ v ] < c [ tmp ] + dis [ i ] ) {
                c [ v ] = c [ tmp ] + dis [ i ] ;
                pree [ v ] = i ;
                pred [ v ] = tmp ;
                if ( ! vis [ v ] ) {
                    vis [ v ] = true ;
                    q . push ( v ) ;
                }
            }
        }
    }
    return  c [ sink ] > - inf ;
} 

void  augment1 ( ) {
    int  u = sink , delta = inf , sum = 0 ;
    while ( u != src ) {
        if ( delta > flt [ pree [ u ] ] )
             delta = flt [ pree [ u ] ] ;
        u = pred [ u ] ;
    }
    u = sink ;
    while ( u != src ) {
        flt [ pree [ u ] ] -= delta ;
        flt [ pree [ u ] ^ 1 ] += delta ;
        sum += delta * dis [ pree [ u ] ] ;
        u = pred [ u ] ;
    }
    mincost += sum ;
}

void  augment2 ( ) {
    int  u = sink , delta = inf , sum = 0 ;
    while ( u != src ) {
        if ( delta > flt [ pree [ u ] ] )
             delta = flt [ pree [ u ] ] ;
        u = pred [ u ] ;
    }
    u = sink ;
    while ( u != src ) {
        flt [ pree [ u ] ] -= delta ;
        flt [ pree [ u ] ^ 1 ] += delta ;
        sum += delta * dis [ pree [ u ] ] ;
        u = pred [ u ] ;
    }
    maxcost += sum ;
}

void  init ( ) {
    memset ( head , 0 , sizeof ( head ) ) ;
    memset ( flt , 0 , sizeof ( flt ) ) ;
    memset ( nxt , 0 , sizeof ( nxt ) ) ;
    memset ( dis , 0 , sizeof ( dis ) ) ;
    memset ( to , 0 , sizeof ( to ) ) ;
}

int  main ( ) {
    scanf ( "%d%d" , & n , & m ) ;
    prp ( ) ; 
    src = 0 ; sink = n + m + 1 ;
    
    for ( int  i = 1 ; i <= n ; i ++ ) 
        scanf ( "%d" , & ck [ i ] ) ;
    for ( int  i = n + 1 ; i <= n + m ; i ++ )
        scanf ( "%d" , & ls [ i ] ) ;
    for ( int  i = 1 ; i <= n ; i ++ )
        for ( int  j = n + 1 ; j <= m + n ; j ++ ) {
            scanf ( "%d" , & x [ i ] [ j ] ) ;
            create ( i , j , inf , x [ i ] [ j ] ) ;
        }
    for ( int  i = 1 ; i <= n ; i ++ )
        create ( src , i , ck [ i ] , 0 ) ;
    for ( int  i = n + 1 ; i <= n + m ; i ++ )
        create ( i , sink , ls [ i ] , 0 ) ;
    while ( spfa1 ( ) )
        augment1 ( ) ;
    init ( ) ;
    
    
    for ( int  i = 1 ; i <= n ; i ++ )
        for ( int  j = n + 1 ; j <= m + n ; j ++ )
            create ( i , j , inf , x [ i ] [ j ] ) ;
    for ( int  i = 1 ; i <= n ; i ++ )
        create ( src , i , ck [ i ] , 0 ) ;
    for ( int  i = n + 1 ; i <= n + m ; i ++ )
        create ( i , sink , ls [ i ] , 0 ) ;
    
    while ( spfa2 ( ) ) 
        augment2 ( ) ;
    
    printf ( "%d\n%d" , mincost , maxcost ) ;
    return  0 ; 
}
Ans

猜你喜欢

转载自www.cnblogs.com/horsepower2001/p/8998054.html