• 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;  
    }
    

      

  • 相关阅读:
    第三天
    第二天
    第一天
    构建之法阅读笔记06
    返回一个一维整数数组中最大子数组的和2
    团队介绍
    软件工程结对作业02
    返回一个整数数组中最大子数组的和
    构建之法阅读笔记05
    暑假周总结二7.22
  • 原文地址:https://www.cnblogs.com/guangheli/p/12562344.html
Copyright © 2020-2023  润新知