首页 > 其他 > 详细

BZOJ 3894 文理分科

时间:2019-02-13 19:50:51      阅读:121      评论:0      收藏:0      [点我收藏+]

如图建图
技术分享图片

#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

*/

BZOJ 3894 文理分科

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!