Nude, architecturally unusual.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 ; }