# # Luo Gu 4313 network flow Arts Division

Topic Portal

analysis

Clearly the network flow, the answer is positive edge weights and subtracting the minimum cut
but how to build chart, the first source and the sink are connected ARTS own satisfaction value
consideration must be removed ARTS point, the first liberal arts and even a source side, and then even INF adjacent
science and sink attached to one side, then even with INF adjacent
both science arts so can not have both the maximum flow = minimum cut, then you can use the network flow for


Code

#include <cstdio>
#include <cctype>
#include <queue>
#define ide(i,j) ((i-1)*m+j)
#define rr register
using namespace std;
const int dx[5]={0,1,0,-1,0},dy[5]={1,0,-1,0,0};
struct node{int y,w,next;}e[550011]; const int inf=707406378;
int dis[30011],ls[30011],n,m,k=1,ans,s,t;
inline signed iut(){
    rr int ans=0,f=1; rr char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans*f;
}
inline void add(int x,int y,int w){
    e[++k]=(node){y,w,ls[x]}; ls[x]=k;
    e[++k]=(node){x,0,ls[y]}; ls[y]=k;
}
inline signed bfs(int s){
    for (rr int i=1;i<=t;++i) dis[i]=0;
    rr queue<int>q; q.push(s); dis[s]=1;
    while (q.size()){
        rr int x=q.front(); q.pop();
        for (rr int i=ls[x];i;i=e[i].next)
        if (e[i].w>0&&!dis[e[i].y]){
            dis[e[i].y]=dis[x]+1;
            if (e[i].y==t) return 1;
            q.push(e[i].y);
        }
    }
    return 0;
}
inline signed dfs(int x,int now){
    if (x==t||!now) return now;
    rr int rest=0,f;
    for (rr int i=ls[x];i;i=e[i].next)
    if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
        rest+=(f=dfs(e[i].y,min(now-rest,e[i].w)));
        e[i].w-=f; e[i^1].w+=f;
        if (now==rest) return rest;
    }
    if (!rest) dis[x]=0;
    return rest;
}
signed main(){
    n=iut(),m=iut(),s=3*n*m+1,t=s+1;
    for (rr int i=1;i<=n;++i)
    for (rr int j=1;j<=m;++j) add(s,ide(i,j),iut());
    for (rr int i=1;i<=n;++i)
    for (rr int j=1;j<=m;++j) add(ide(i,j),t,iut());
    for (rr int i=1;i<=n;++i)
    for (rr int j=1;j<=m;++j) add(s,ide(i,j)+n*m,iut());
    for (rr int i=1;i<=n;++i)
    for (rr int j=1;j<=m;++j) add(ide(i,j)+2*n*m,t,iut());
    for (rr int i=2;i<=k;i+=2) ans+=e[i].w;
    for (rr int i=1;i<=n;++i)
    for (rr int j=1;j<=m;++j)
    for (rr int k=0;k<5;++k){
        rr int x=i+dx[k],y=j+dy[k];
        if (x<1||x>n||y<1||y>m) continue;
        add(ide(i,j)+n*m,ide(x,y),inf);
        add(ide(i,j),ide(x,y)+2*n*m,inf);
    }
    while (bfs(s)) ans-=dfs(s,inf);
    return !printf("%d",ans);
}

Guess you like

Origin www.cnblogs.com/Spare-No-Effort/p/12355141.html