zoukankan      html  css  js  c++  java
  • [BZOJ2132] 圈地计划

    Time Limit: 2 Sec  Memory Limit: 256 MB
    Submit: 1350  Solved: 637
    [Submit][Status][Discuss]

    Description

    最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地。据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域。GDOI要求将这些区域分为商业区和工业区来开发。根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值。更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益。另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(I,j)的区域,则这块区域能增加k×Cij收益。经过Tiger.S教授的勘察,收益矩阵A,B,C都已经知道了。你能帮GDOI求出一个收益最大的方案么?

    Input

    输入第一行为两个整数,分别为正整数N和M,分别表示区域的行数和列数;第2到N+1列,每行M个整数,表示商业区收益矩阵A;第N+2到2N+1列,每行M个整数,表示工业区收益矩阵B;第2N+2到3N+1行,每行M个整数,表示相邻额外收益矩阵C。第一行,两个整数,分别是n和m(1≤n,m≤100);

    任何数字不超过1000”的限制

    Output

    输出只有一行,包含一个整数,为最大收益值。

    Sample Input

    3 3
    1 2 3
    4 5 6
    7 8 9
    9 8 7
    6 5 4
    3 2 1
    1 1 1
    1 3 1
    1 1 1

    Sample Output

    81
    【数据规模】
    对于100%的数据有N,M≤100

    HINT

     数据已加强,并重测--2015.5.15

    思路

    最小割;

    黑白染色,对于每个黑点A,S->A:W商业,A->T:W工业,

    对于每个白点B,S->B:W工业,B->T:W商业,对于每对有关系的两点A,B,A<–>B:c1+c2。

    by:http://hzwer.com/2418.html

    代码实现

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=300;
     4 const int maxm=maxn*maxn;
     5 inline int min_(int x,int y){return x<y?x:y;}
     6 inline int swap_(int&x,int&y){x^=y,y^=x,x^=y;}
     7 int n,m,s,t,ans;
     8 int a;
     9 int ind[maxn][maxn],bus[maxn][maxn],com[maxn][maxn];
    10 int h[maxm],hs=1,et[maxm],ew[maxm],en[maxm];
    11 void add(int u,int v,int w){++hs,et[hs]=v,ew[hs]=w,en[hs]=h[u],h[u]=hs;}
    12 int nh,nl;
    13 int hb[]={0,0,1,-1};
    14 int lb[]={1,-1,0,0};
    15 int q[maxm],head,tail;
    16 int d[maxm];
    17 void bfs(){
    18     memset(d,0,sizeof(d));
    19     head=tail=0;
    20     q[head++]=s,d[s]=1;
    21     while(head>tail){
    22         a=q[tail++];
    23         for(int i=h[a];i;i=en[i])
    24         if(!d[et[i]]&&ew[i]){
    25             d[et[i]]=d[a]+1;
    26             if(et[i]==t) return;
    27             q[head++]=et[i];
    28         }
    29     }
    30 }
    31 int ap(int k,int w){
    32     if(k==t) return w;
    33     int dw=w;
    34     for(int i=h[k];i&&dw;i=en[i])
    35     if(ew[i]&&d[et[i]]==d[k]+1){
    36         int wt=ap(et[i],min_(dw,ew[i]));
    37         ew[i]-=wt,ew[i^1]+=wt,dw-=wt;
    38     }
    39     if(w==dw) d[k]=0;
    40     return w-dw;
    41 }
    42 void Dinic(){while(bfs(),d[t]) ans-=ap(s,1e5);}
    43 int main(){
    44     scanf("%d%d",&n,&m);
    45     s=0,t=1;
    46     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&ind[i][j]),ans+=ind[i][j];
    47     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&bus[i][j]),ans+=bus[i][j];
    48     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&com[i][j]);
    49     for(int i=1;i<=n;i++)
    50     for(int j=1;j<=m;j++){
    51         if((i^j)&1) swap_(ind[i][j],bus[i][j]);
    52         add(s,i*m+j,ind[i][j]),add(i*m+j,s,0);
    53         add(i*m+j,t,bus[i][j]),add(t,i*m+j,0);
    54         if((i^j)&1) for(int k=0;k<4;k++){
    55             nh=i+hb[k],nl=j+lb[k];
    56             if(nh&&nh<=n&&nl&&nl<=m){
    57                 add(i*m+j,nh*m+nl,com[i][j]+com[nh][nl]);
    58                 add(nh*m+nl,i*m+j,com[i][j]+com[nh][nl]);
    59                 ans+=com[i][j]+com[nh][nl];
    60             }
    61         }
    62     }
    63     Dinic();
    64     printf("%d",ans);
    65     return 0;
    66 }
  • 相关阅读:
    MySQL数据库的创建&删除&选择
    JS实现异步的几种方式
    十种排序算法实例说明总结
    常用的bug管理工具
    Bootstrap+Hbuilder
    从菜鸟的视角看测试!
    安装numpy和matplotlib
    Eclipse在线安装svn
    重新打个招呼
    <USACO09JAN>气象测量/气象牛The Baric Bovineの思路
  • 原文地址:https://www.cnblogs.com/J-william/p/7074605.html
Copyright © 2011-2022 走看看