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
", 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

*/
原文地址:https://www.cnblogs.com/Pickupwin/p/BZOJ3894.html