P4313 文理分科

【题意】

 

 

【分析】

典型的二者选其一模型

 

【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,tot;
const int maxn=1e5+5;
const ll inf=1e18;
const int INF=0x3f3f3f3f;
int head[maxn],ecnt=1;
struct edge
{
    int to,nxt;
    ll v;
}e[maxn*5];
void add(int x,int y,ll z)
{
    e[++ecnt].nxt=head[x]; e[ecnt].to=y; e[ecnt].v=z; head[x]=ecnt;
    e[++ecnt].nxt=head[y]; e[ecnt].to=x; e[ecnt].v=0; head[y]=ecnt;
}
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};
int s,t,dep[maxn],vis[maxn],cur[maxn];
ll ans;
bool bfs()
{
    queue <int> q;
    for(int i=s;i<=tot;i++) dep[i]=INF,cur[i]=head[i];
    q.push(s); dep[s]=0;
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt)
        {
            int to=e[i].to;
            if(e[i].v && dep[to]>dep[u]+1)
            {
                dep[to]=dep[u]+1;
                if(!vis[to]) vis[to]=1,q.push(to);
            }
        }
    }
    return (dep[t]!=INF);
}
ll dfs(int u,ll flow)
{
    if(u==t) return flow;
    ll res=0;
    for(int &i=cur[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(e[i].v && dep[to]==dep[u]+1)
        {
            ll tmp=dfs(to,min(flow-res,e[i].v));
            if(tmp)
            {
                e[i].v-=tmp; e[i^1].v+=tmp;
                res+=tmp;
                if(res==flow) break; 
            }
        }
    }
    return res;
}
int main()
{
//    freopen("a.in","r",stdin);
//    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    ll x;
    s=0; t=n*m+1;
    tot=t;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&x);
            ans+=x;
            add(s,(i-1)*m+j,x);
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&x);
            ans+=x;
            add((i-1)*m+j,t,x);
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&x); ans+=x; 
            add(s,++tot,x);
            for(int k=0;k<=4;k++)
            {
                int tox=i+dx[k];
                int toy=j+dy[k];
                if(tox<1 || toy<1 || tox>n || toy>m) continue;
                add(tot,(tox-1)*m+toy,inf);
            }
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&x); ans+=x;
            add(++tot,t,x);
            for(int k=0;k<=4;k++)
            {
                int tox=i+dx[k];
                int toy=j+dy[k];
                if(tox>=1 && toy>=1 && tox<=n && toy<=m)
                    add((tox-1)*m+toy,tot,inf);
            }
        }        
    while(bfs())
        ans-=dfs(s,inf);
    printf("%lld",ans);
    return 0;
}

 

posted @ 2021-06-03 15:34  andyc_03  阅读(53)  评论(0)    收藏  举报