BZOJ 3894 文理分科
如图建图
#include <cstdio>
#include <queue>
#include <algorithm>
using std::queue;
using std::min;
const int INF=1034567890;
const int MAXN=111;
const int MAXM=111;
const int MAXV=3*MAXN*MAXM;
const int MAXE=14*MAXN*MAXM;
int dx[4]={0, 0, 1, -1};
int dy[4]={1, -1, 0, 0};
int N, M;
bool Norm(int i, int j){
return i>=1 && i<=N && j>=1 && j<=M;
}
int A[MAXN][MAXM], B[MAXN][MAXM], As[MAXN][MAXM], Bs[MAXN][MAXM];
struct Vert{
int FE;
int Lev, Bfn;
} V[MAXV];
int Vcnt;
int Sink, Sour;
int P[MAXN][MAXM], Ap[MAXN][MAXM], Bp[MAXN][MAXM];
struct Edge{
int y, f, next, neg;
} E[MAXE<<1];
int Ecnt;
void addE(int a, int b, int f){
++Ecnt;
E[Ecnt].y=b;E[Ecnt].f=f;E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;E[Ecnt].neg=Ecnt+1;
++Ecnt;
E[Ecnt].y=a;E[Ecnt].f=0;E[Ecnt].next=V[b].FE;V[b].FE=Ecnt;E[Ecnt].neg=Ecnt-1;
}
int BFN;
queue<int> Q;
bool BFS(int at=Sour){
++BFN;
V[at].Lev=1;
Q.push(at);
V[at].Bfn=BFN;
while(!Q.empty()){
at=Q.front();Q.pop();
for(int k=V[at].FE, to;k;k=E[k].next){
if(E[k].f<=0) continue;
to=E[k].y;
if(V[to].Bfn==BFN) continue;
V[to].Lev=V[at].Lev+1;
Q.push(to);
V[to].Bfn=BFN;
}
}
return V[Sink].Bfn==BFN;
}
int DFS(int at=Sour, int inc=INF){
if(at==Sink || inc<=0) return inc;
int ret=0, out;
for(int k=V[at].FE, to;k;k=E[k].next){
if(E[k].f<=0) continue;
to=E[k].y;
if(V[to].Lev!=V[at].Lev+1) continue;
out=DFS(to, min(E[k].f, inc));
inc-=out;ret+=out;
E[k].f-=out;E[E[k].neg].f+=out;
}
if(inc>0) V[at].Lev=-1;
return ret;
}
int DINIC(){
int ret=0;
while(BFS()) ret+=DFS();
return ret;
}
int main(){
scanf("%d%d", &N, &M);
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
scanf("%d", &A[i][j]);
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
scanf("%d", &B[i][j]);
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
scanf("%d", &As[i][j]);
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
scanf("%d", &Bs[i][j]);
Sour=++Vcnt;Sink=++Vcnt;
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j){
P[i][j]=++Vcnt;
Ap[i][j]=++Vcnt;
Bp[i][j]=++Vcnt;
}
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j){
addE(Sour, P[i][j], A[i][j]);
addE(Sour, Ap[i][j], As[i][j]);
addE(P[i][j], Sink, B[i][j]);
addE(Bp[i][j], Sink, Bs[i][j]);
addE(Ap[i][j], P[i][j], INF);
addE(P[i][j], Bp[i][j], INF);
for(int k=0;k<4;++k){
if(Norm(i+dx[k], j+dy[k])){
addE(Ap[i][j], P[i+dx[k]][j+dy[k]], INF);
addE(P[i+dx[k]][j+dy[k]], Bp[i][j], INF);
}
}
}
int Sum=0;
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
Sum+=A[i][j]+B[i][j]+As[i][j]+Bs[i][j];
int Ans=DINIC();
printf("%d\n", Sum-Ans);
return 0;
}
/*
3 4
13 2 4 13
7 13 8 12
18 17 0 5
8 13 15 4
11 3 8 11
11 18 6 5
1 2 3 4
4 2 3 2
3 1 0 4
3 2 3 2
0 2 2 1
0 2 4 4
*/