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

    网络流/最小割


      Orz Hzwer

      这类大概是最小割建模中的经典应用吧……

      黑白染色,然后反转黑色的技巧感觉很巧妙!这个转化太神奇了……

      1 /**************************************************************
      2     Problem: 2132
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:0 ms
      7     Memory:6252 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 2132
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstring>
     14 #include<cstdlib>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 #define FOR for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
     21 #define pb push_back
     22 using namespace std;
     23 inline int getint(){
     24     int v=0,sign=1; char ch=getchar();
     25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     27     return v*sign;
     28 }
     29 const int N=10010,M=300000,INF=~0u>>2;
     30 const int fx[]={1,0,-1,0},
     31           fy[]={0,1,0,-1};
     32 typedef long long LL;
     33 /******************tamplate*********************/
     34 int n,m,a[101][101],b[101][101],c[101][101],color[101][101],tot,ans;
     35 struct edge{
     36     int from,to,v;
     37 };
     38 inline int pack(int i,int j){ return (i-1)*m+j; }
     39 struct Net{
     40     edge E[M];
     41     int head[N],next[M],cnt;
     42     bool vis[110][110];
     43     void ins(int x,int y,int v){
     44         E[++cnt]=(edge){x,y,v};
     45         next[cnt]=head[x]; head[x]=cnt;
     46     }
     47     void add(int x,int y,int v){
     48         ins(x,y,v); ins(y,x,0);
     49     }
     50     void add2(int x,int y,int v){
     51         ins(x,y,v); ins(y,x,v);
     52     }
     53     int s,t,d[N],Q[N];
     54     void init(){
     55         n=getint();m=getint();
     56         cnt=1;tot=ans=0;
     57         s=0;t=n*m+1;
     58         int x,y;
     59         memset(a,-1,sizeof a);
     60         FOR a[i][j]=getint();
     61         FOR b[i][j]=getint();
     62         FOR c[i][j]=getint();
     63         FOR if ((i+j)&1) color[i][j]=1;
     64         FOR{
     65             if (color[i][j]) swap(a[i][j],b[i][j]);
     66             tot+=a[i][j]+b[i][j];
     67             add(s,pack(i,j),a[i][j]);
     68             add(pack(i,j),t,b[i][j]);
     69             if (color[i][j]) rep(k,4){
     70                 int tx=i+fx[k],ty=j+fy[k];
     71                 if (!tx||!ty||tx>n||ty>m) continue;
     72                 add2(pack(i,j),pack(tx,ty),c[i][j]+c[tx][ty]);
     73                 tot+=c[i][j]+c[tx][ty];
     74             }
     75         }
     76     }
     77     bool mklevel(){
     78         memset(d,-1,sizeof d);
     79         d[s]=0;
     80         int l=0,r=-1;
     81         Q[++r]=s;
     82         while(l<=r){
     83             int x=Q[l++];
     84             for(int i=head[x];i;i=next[i])
     85                 if (d[E[i].to]==-1 && E[i].v){
     86                     d[E[i].to]=d[x]+1;
     87                     Q[++r]=E[i].to;
     88                 }
     89         }
     90         return d[t]!=-1;
     91     }
     92     int dfs(int x,int a){
     93         if(x==t)return a;
     94         int flow=0;
     95         for(int i=head[x];i && flow<a;i=next[i])
     96             if (d[E[i].to]==d[x]+1 && E[i].v){
     97                 int f=dfs(E[i].to,min(a-flow,E[i].v));
     98                 E[i].v-=f;
     99                 E[i^1].v+=f;
    100                 flow+=f;
    101             }
    102         if (!flow) d[x]=-1;
    103         return flow;
    104     }
    105     void Dinic(){
    106         while(mklevel()) ans+=dfs(s,INF);
    107     }
    108 }G1;
    109 int main(){
    110 #ifndef ONLINE_JUDGE
    111     freopen("2132.in","r",stdin);
    112     freopen("2132.out","w",stdout);
    113 #endif
    114     G1.init(); G1.Dinic();
    115     printf("%d
    ",tot-ans);
    116     return 0;
    117 }
    View Code

    2132: 圈地计划

    Time Limit: 2 Sec  Memory Limit: 256 MB
    Submit: 515  Solved: 228
    [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

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    数据库中char、varchar、varchar2、nvarchar之间的关系
    Oracle中scott用户下基本表练习SQL语句
    判断一个数是否是素数
    阿里P7前端需要哪些技能
    react Native 踩坑记录
    流程节点(2018.7.31)
    在centos7下手工安装和配置Nginx
    微信公众号开发
    nodejs 实战
    数据库权限表的设计
  • 原文地址:https://www.cnblogs.com/Tunix/p/4338190.html
Copyright © 2011-2022 走看看