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

    bzoj2132圈地计划

    题意:

    一块土地可以纵横划分为N×M块小区域。于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益。而如果区域(i,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(i,j)的区域,则这块区域能增加k×Cij收益。已知收益矩阵A,B,C,求收益最大值。

    题解:

    因为附加收益不是两两之间的,所以不用考虑除以2的问题。由于需要两块土地属性不同,所以对整个棋盘进行黑白染色。如果一块土地A为黑色,则s->A :c[A商] A->T:c[A工],如果为白色则反之s->A:c[A工] A->T:c[A商],对于相邻的AB A<->B c[A合]+c[B合]。最后答案是所有收益和减最小割。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define visit(i,j) for(int i=g[j];i!=-1;i=es[i].n)
     7 #define INF 0x3fffffff
     8 using namespace std;
     9 
    10 struct e{int t,c,n;}; e es[500000]; int ess,g[20000];
    11 inline void pe(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,0,g[t]}; g[t]=ess;}
    12 inline void pe2(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,c,g[t]}; g[t]=ess;}
    13 inline void init(){ess=-1; memset(g,-1,sizeof(g));}
    14 queue <int> q; int h[20000];
    15 bool bfs(int s,int t){
    16     while(! q.empty())q.pop(); memset(h,-1,sizeof(h)); q.push(s); h[s]=0;
    17     while(! q.empty()){
    18         int x=q.front(); q.pop();
    19         visit(i,x)if(es[i].c&&h[es[i].t]==-1){h[es[i].t]=h[x]+1; q.push(es[i].t);}
    20     }
    21     if(h[t]==-1)return 0;else return 1;
    22 }
    23 int dfs(int x,int t,int f){
    24     if(x==t)return f; int u=0;
    25     visit(i,x)if(es[i].c&&h[es[i].t]==h[x]+1){
    26         int w=dfs(es[i].t,t,min(f,es[i].c));
    27         f-=w; u+=w; es[i].c-=w; es[i^1].c+=w; if(f==0)return u;
    28     }
    29     if(!u)h[x]=-1; return u;
    30 }
    31 int dinic(int s,int t){int f=0; while(bfs(s,t))f+=dfs(s,t,INF); return f;}
    32 int a1[200][200],a2[200][200],a3[200][200],tot,n,m,s,t; bool col[200][200];
    33 inline int cg(int x,int y){return (x-1)*m+y;}
    34 int main(){
    35     scanf("%d%d",&n,&m); tot=0;
    36     inc(i,1,n)inc(j,1,m)scanf("%d",&a1[i][j]),tot+=a1[i][j];
    37     inc(i,1,n)inc(j,1,m)scanf("%d",&a2[i][j]),tot+=a2[i][j];
    38     inc(i,1,n)inc(j,1,m)scanf("%d",&a3[i][j]);
    39     s=0; t=n*m+1; init();inc(i,1,n)inc(j,1,m){col[i][j]=(i+j)&1;}
    40     inc(i,1,n)inc(j,1,m){
    41         if(col[i][j])pe(s,cg(i,j),a1[i][j]),pe(cg(i,j),t,a2[i][j]);else pe(s,cg(i,j),a2[i][j]),pe(cg(i,j),t,a1[i][j]);
    42         if(i!=n)pe2(cg(i,j),cg(i+1,j),a3[i][j]+a3[i+1][j]),tot+=(a3[i][j]+a3[i+1][j]);
    43         if(j!=m)pe2(cg(i,j),cg(i,j+1),a3[i][j]+a3[i][j+1]),tot+=(a3[i][j]+a3[i][j+1]);
    44     }
    45     printf("%d",tot-dinic(s,t));
    46     return 0;
    47 }

    20160324

  • 相关阅读:
    函数【二】嵌套/作用域/名称空间
    内核模块加载错误 “Invalid module format” 解决办法
    linux oops调试
    linux 工具
    makefile 嵌套
    scheduling while atomic 出现的错误
    Windows下VSCode编译调试c/c++
    window markdown 编辑器
    linux 比较命令
    openwrt 加入nand flash的支持
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5656815.html
Copyright © 2011-2022 走看看