#include
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 ;
}
裸题