#include <iostream>
#include <cstring>
#include <queue>
using namespace std ;
#define int long long
const int N = 200005 , INF = 0x3f3f3f3f3f3f3f3f ;
const int dx[] = { 0 , 1 , 0 , -1 } , dy[] = { 1 , 0 , -1 , 0 } ;
int n , m , s , t , ans , dis[N] , wv[105][105] ;
struct Edge
{
int nxt , to , len ;
} edge[N*20] ;
int cnt = 0 , head[N] ;
void insert ( int u , int v , int w )
{
edge [ ++ cnt ] .nxt = head [ u ] ;
edge [ cnt ] .to = v ;
edge [ cnt ] .len = w ;
head [ u ] = cnt ;
}
queue < int > q ;
bool bfs ( )
{
memset ( dis , 0 , sizeof ( dis ) ) ;
dis [ s ] = 1 ;
q .push ( s ) ;
while ( ! q .empty ( ) )
{
int x = q .front ( ) ; q .pop ( ) ;
for ( int i = head [ x ] ; i ; i = edge [ i ] .nxt )
{
int y = edge [ i ] .to ;
if ( dis [ y ] || ! edge [ i ] .len )
continue ;
dis [ y ] = dis [ x ] + 1 ;
q .push ( y ) ;
}
}
return dis [ t ] ;
}
int dfs ( int x , int now )
{
if ( x == t )
return now ;
int res = now ;
for ( int i = head [ x ] ; i && res ; i = edge [ i ] .nxt )
{
int y = edge [ i ] .to ;
if ( dis [ y ] != dis [ x ] + 1 || ! edge [ i ] .len )
continue ;
int w = dfs ( y , min ( res , edge [ i ] .len ) ) ;
if ( ! w ) dis [ y ] = -1 ;
edge [ i ] .len -= w ;
edge [ i ^ 1 ] .len += w ;
res -= w ;
}
return now - res ;
}
int id ( int x , int y )
{
return ( x - 1 ) * m + y ;
}
signed main ( )
{
cin >> n >> m ;
s = n * m + 1 ;
t = s + 1 ;
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= m ; ++ j )
{
int x ;
cin >> x ;
if ( ( i + j ) & 1 )
insert ( s , id ( i , j ) , x ) ,
insert ( id ( i , j ) , s , 0 ) ;
else
insert ( id ( i , j ) , t , x ) ,
insert ( t , id ( i , j ) , 0 ) ;
ans += x ;
}
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= m ; ++ j )
{
int x ;
cin >> x ;
if ( ( i + j ) & 1 )
insert ( id ( i , j ) , t , x ) ,
insert ( t , id ( i , j ) , 0 ) ;
else
insert ( s , id ( i , j ) , x ) ,
insert ( id ( i , j ) , s , 0 ) ;
ans += x ;
}
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= m ; ++ j )
cin >> wv [ i ] [ j ] ;
for ( int i = 1 ; i <= n ; ++ i )
for ( int j = 1 ; j <= m ; ++ j )
for ( int c = 0 ; c < 2 ; ++ c )
{
int ii = i + dx [ c ] , jj = j + dy [ c ] ;
if ( ii < 1 || jj < 1 || ii > n || jj > m )
continue ;
insert ( id ( i , j ) , id ( ii , jj ) , wv [ i ] [ j ] + wv [ ii ] [ jj ] ) ;
insert ( id ( ii , jj ) , id ( i , j ) , wv [ i ] [ j ] + wv [ ii ] [ jj ] ) ;
ans += wv [ i ] [ j ] + wv [ ii ] [ jj ] ;
}
int tmp = 0 ;
while ( bfs ( ) )
while ( tmp = dfs ( s , INF ) )
ans -= tmp ;
cout << ans << '\n' ;
return 0 ;
}
看题解了,感觉没啥两样啊