BZOJ 1324: Exca王者之剑 最小割+黑白染色

注意:在最小割轻易不要连流量为无穷大的双向边(这就意味着这两个点必须属于一个集合里了) 

code:   

#include <bits/stdc++.h>   
#define N 10005             
#define I(s) freopen(s".in","r",stdin)  
#define O(s) freopen(s".out","w",stdout) 
#define setIO(s) I(s)    
const int dx[]={-1,0,1,0};  
const int dy[]={0,1,0,-1};   
using namespace std;   
const int INF=200000;  
const int inf=2000000001;        
namespace net
{
    struct Edge    
    {
        int u,v;
        int c;
        Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}
    }; 
    queue<int>q;
    vector<Edge>edges;
    vector<int>G[N];
    int vv[N],vis[N],d[N],bo[N],s,t;     
    void add(int u,int v,int c)
    {
        edges.push_back(Edge(u,v,c));
        edges.push_back(Edge(v,u,0));
        int o=edges.size();
        G[u].push_back(o-2);
        G[v].push_back(o-1);    
    }  
    int dfs(int x,int cur)
    {
        if(x==t)
            return cur;
        int an=0,flow=0;
        for(int i=vv[x];i<G[x].size();++i,++vv[x])     
        {
            Edge e=edges[G[x][i]];
            if(e.c>0&&d[e.v]==d[x]+1)
            {   
                an=dfs(e.v,min(cur,e.c)); 
                if(an)
                {
                    cur-=an;
                    flow+=an;          
                    edges[G[x][i]].c-=an;
                    edges[G[x][i]^1].c+=an;  
                    if(!cur)
                        break; 
                }
            }
        }
        return flow;
    }
    int bfs()
    {  
        memset(vis,0,sizeof(vis));
        d[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<G[u].size();++i)
            {
                if(edges[G[u][i]].c>0)
                {
                    int v=edges[G[u][i]].v;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        d[v]=d[u]+1;
                        q.push(v);
                    }
                }
            }
        }
        return vis[t];
    } 
    int maxflow()
    {
        int re=0;
        while(bfs()) 
        {
            memset(vv,0,sizeof(vv));         
            re+=(int)dfs(s,inf);
        }
        return re;
    }           
};      
int n,m,a[103][103],id[103][103];  
int main() 
{ 
    // setIO("input");     
    scanf("%d%d",&n,&m);   
    int SUM=0,tim=0; 
    for(int i=1;i<=n;++i)  
        for(int j=1;j<=m;++j) 
            scanf("%d",&a[i][j]),SUM+=a[i][j],id[i][j]=++tim;  
    int s=0,t=id[n][m]+2;  
    net::s=s,net::t=t;   
    for(int i=1;i<=n;++i) 
    {
        for(int j=1;j<=m;++j) 
        {
            if((i+j)&1)         
            {
                net::add(s,id[i][j],a[i][j]);          
                for(int k=0;k<4;++k) 
                {        
                    int X=i+dy[k],Y=j+dx[k];  
                    if(X>=1&&X<=n&&Y>=1&&Y<=m)           
                    { 
                        net::add(id[i][j],id[X][Y],10000);    
                    }
                }
            }
            else net::add(id[i][j],t,a[i][j]);   
        }
    }
    printf("%d
",SUM-net::maxflow());   
    return 0;  
}

  

原文地址:https://www.cnblogs.com/guangheli/p/12562344.html