Network Flow 24 Questions Luogu 4015 Transportation Problems

Nude, architecturally unusual.

#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 = before [u];
    }
    u = sink ;
    while ( u != src ) {
        flt [pree [u]] - = delta;
        flt [pree [u] ^ 1 ] + = delta;
        sum + = delta * dis [pree [u]];
        u = before [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 = before [u];
    }
    u = sink ;
    while ( u != src ) {
        flt [pree [u]] - = delta;
        flt [pree [u] ^ 1 ] + = delta;
        sum + = delta * dis [pree [u]];
        u = before [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 ; 
}
Years

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325353815&siteId=291194637
Recommended