https://www.luogu.com.cn/blog/CJL/solution-p4313
#include<iostream>
#include<cstring>
using namespace std;
const int N=400020;
#define int long long
const int INF=1e9;
int n,m,S,T;
int h[N],e[N],ne[N],idx,w[N];
int q[N],d[N],cur[N];
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
e[idx]=a,w[idx]=0,ne[idx]=h[b],h[b]=idx++;
}
bool bfs()
{
int hh=0;
int tt=0;
memset(d,-1,sizeof d);
q[0]=S;
d[S]=0;
cur[S]=h[S];
while(hh<=tt)
{
int t=q[hh++];
for(int i=h[t]; i!=-1; i=ne[i])
{
int ver=e[i];
if(d[ver]==-1&&w[i])
{
d[ver]=d[t]+1;
cur[ver]=h[ver];
if(ver==T)
return true;
q[++tt]=ver;
}
}
}
return false;
}
int find(int u,int limit)
{
if(u==T)
return limit;
int flow=0;
for(int i=cur[u]; ~i&&flow<limit; i=ne[i])
{
cur[u]=i;
int ver=e[i];
if(d[ver]==d[u]+1&&w[i])
{
int t=find(ver,min(w[i],limit-flow));
if(!t)
d[ver]=-1;
w[i]-=t;
w[i^1]+=t;
flow+=t;
}
}
return flow;
}
int dinic()
{
int r=0;
int flow;
while(bfs())
while(flow=find(S,INF))
r+=flow;
return r;
}
int get(int i,int j)
{
return (i-1)*m+j;
}
bool check(int x,int y)
{
return x>=1&&x<=n&&y>=1&&y<=m;
}
signed main()
{
memset(h,-1,sizeof h);
cin>>n>>m;
int tot=n*m;
S=0,T=++tot;
int sum=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int x;
cin>>x;
sum+=x;
add(S,get(i,j),x);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int x;
cin>>x;
sum+=x;
add(get(i,j),T,x);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int x;
cin>>x;
sum+=x;
add(S,++tot,x);
add(tot,get(i,j),INF);
if(check(i-1,j))
add(tot,get(i-1,j),INF);
if(check(i,j-1))
add(tot,get(i,j-1),INF);
if(check(i+1,j))
add(tot,get(i+1,j),INF);
if(check(i,j+1))
add(tot,get(i,j+1),INF);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int x;
cin>>x;
sum+=x;
add(++tot,T,x);
add(get(i,j),tot,INF);
if(check(i-1,j))
add(get(i-1,j),tot,INF);
if(check(i+1,j))
add(get(i+1,j),tot,INF);
if(check(i,j+1))
add(get(i,j+1),tot,INF);
if(check(i,j-1))
add(get(i,j-1),tot,INF);
}
cout<<sum-dinic()<<endl;
}