zoukankan      html  css  js  c++  java
  • BZOJ 2132 圈地计划

    题目传送门

    分析:

    首先A和B2选1就是一组矛盾关系

    然后相邻的两个格子选相同的也是一种矛盾

    我们可以把格子染成黑白颜色,像国际象棋棋盘那样

    对于黑格子,与S连容量为A的边,与T连容量为B的边

    对于白格子,与S连容量为B的边,与T连容量为A的边

    然后相邻格子,连容量为两个格子C之和的边

    考虑正确性

    同一个格子,A和B必须割一个

    对于相邻格子,选相同和额外收益必须割一个

    没有问题

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    
    #define maxt 10005
    #define maxn 105
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    int n,m,S,T;
    int fir[maxt],nxt[20*maxt],to[20*maxt],cap[20*maxt],cnt;
    int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
    int col[maxn][maxn];
    long long ans;
    int h[maxt];
    
    inline int getid(int i,int j){return (i-1)*m+j;}
    inline void newnode(int u,int v,int w)
    {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;}
    inline void insert(int u,int v,int w)
    {newnode(u,v,w),newnode(v,u,0);}
    
    inline bool bfs()
    {
        memset(h,-1,sizeof h);
        queue<int>Q;h[S]=0,Q.push(S);
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();
            for(int i=fir[u];i;i=nxt[i])
                if(cap[i]&&!~h[to[i]])h[to[i]]=h[u]+1,Q.push(to[i]);
        }
        return ~h[T];
    }
    
    inline int dfs(int u,int flow)
    {
        if(u==T)return flow;
        int used=0;
        for(int i=fir[u];i;i=nxt[i])
            if(cap[i]&&h[to[i]]==h[u]+1)
            {
                int w=flow-used;
                w=dfs(to[i],min(cap[i],w));
                cap[i]-=w,cap[i^1]+=w,used+=w;
                if(used==flow)return flow;
            }
        if(!used)h[u]=-1;
        return used;
    }
    
    inline void dinic(){while(bfs())ans-=dfs(S,INF);}
    
    int main()
    {
        n=getint(),m=getint();S=n*m+1,T=S+1;cnt=1;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)ans+=a[i][j]=getint();
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)ans+=b[i][j]=getint();
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)c[i][j]=getint();
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)col[i][j]=(i+j)&1;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
        {
            if(col[i][j])swap(a[i][j],b[i][j]);
            insert(S,getid(i,j),a[i][j]),insert(getid(i,j),T,b[i][j]);
            if(i>1)ans+=c[i][j],insert(getid(i,j),getid(i-1,j),c[i][j]+c[i-1][j]);
            if(i<n)ans+=c[i][j],insert(getid(i,j),getid(i+1,j),c[i][j]+c[i+1][j]);
            if(j>1)ans+=c[i][j],insert(getid(i,j),getid(i,j-1),c[i][j]+c[i][j-1]);
            if(j<m)ans+=c[i][j],insert(getid(i,j),getid(i,j+1),c[i][j]+c[i][j+1]);
        }
        dinic();
        printf("%lld
    ",ans);
    }
    View Code
  • 相关阅读:
    P6057 [加油武汉]七步洗手法
    LC 1349. Maximum Students Taking Exam (Hungarian / Max Flow)
    P1879 [USACO06NOV]玉米田Corn Fields
    P1433 吃奶酪 (TSP)
    LC 1349. Maximum Students Taking Exam
    获取XML中的值
    TimeZoneInfo类的使用
    XML 克隆节点
    网络协议概述:物理层、连接层、网络层、传输层、应用层详解
    Vuex
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12006133.html
Copyright © 2011-2022 走看看