Squares problem access (network flow)

Grid access issue (luogu)

Solution

It can be used to solve network flow on the "exclusion" of

Minimum assume that all points are selected, you can not choose certain points the selection of a legitimate program, do not choose to obtain these points the sum of the value

Lenovo to cut the minimum minimum

The (+ abscissa ordinate) parity FIG divided into two parts

You can not choose between the point even side (direction even - odd), due to "cut" can not be cut off point can not choose between the relationship, so it's endless flow should be positive

And then flow from even a starting point for each point to even part of the value of this point edge, from every point of odd to even a part of the flow for the end edge value of this point,

He said they did not vote for it to lose value

The maximum running flow (i.e., minimum cut)

Code

 

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e4+10,M=1e5;
int head[N],nxt[M],ver[M],edge[M],tot=1;
int s,t,n,m,d[N],x,maxflow,flow,sum,inf=1<<30;
int id(int x,int y)
{
    return (x-1)*m+y;
}
void add(int u,int v,int w)
{
    far [ ++ to] = v, nxt [up] = head [u], edge [in] = w, head [u] = to;
    far [ ++ to] = u, nxt [up] = head [v], edge [in] = 0 , head [v] = to;
}
int bfs()
{
    queue <int> q;
    memset(d,0,sizeof(d));
    d[s]=1,q.push(s);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x],y;i;i=nxt[i])
            if(edge[i]>0 && !d[y=ver[i]])
            {
                d[y]=d[x]+1;
                q.push(y);
                if(y==t) return 1;
            }
    }
    return 0;
}
int dinic(int x,int flow)
{
    if(x==t) return flow;
    int rest=flow;
    for(int i=head[x],y;i && rest;i=nxt[i])
        if(edge[i]>0 && d[y=ver[i]]==d[x]+1)
        {
            int k=dinic(y,min(edge[i],rest));
            if(!k) d[y]=0;
            edge[i]-=k,edge[i^1]+=k;
            rest-=k;
        }
    return flow-rest;
}
int main ()
{
    scanf("%d%d",&n,&m);
    s=0,t=n*m+1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&x);
            sum+=x;
            if((i+j)%2) 
            {
                add(id(i,j),t,x);
                continue;
            }
            add(s,id(i,j),x);
            if(i>1) add(id(i,j),id(i-1,j),inf);
            if(i<n) add(id(i,j),id(i+1,j),inf);
            if(j>1) add(id(i,j),id(i,j-1),inf);
            if(j<m) add(id(i,j),id(i,j+1),inf);
        }
    while(bfs()) while(flow=dinic(s,1<<30)) maxflow+=flow;
    printf("%d\n",sum-maxflow);
    return 0;
}

 

 

 

Guess you like

Origin www.cnblogs.com/hsez-cyx/p/12407490.html
Recommended