• 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
    
    */
    
  • 相关阅读:
    python3----练习题(斐波那契)
    python3----运算符
    python3----函数、匿名函数
    python3----生成器generator(yield)
    Python捕获异常
    OS模块
    发送邮件
    IO文件读写
    Unittest框架概念
    生成报告
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/BZOJ3894.html
Copyright © 2020-2023  润新知