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

    很显然是一个最小割的模型,将网格图黑白染色分为两类,黑的向S连工业费用,向T连商业费用,白的反过来即可
    然后对于相邻的点,连上两个点的C之和(因为会产生两个),当然也可以变成两条边,就不需要存下C矩阵了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 10005
     4 struct ji{
     5     int nex,to,len;
     6 }edge[N*50];
     7 queue<int>q;
     8 int E,n,m,x,ans,dx[4]={-1,0,0,1},dy[4]={0,-1,1,0},head[N],d[N],work[N];
     9 int id(int x,int y){
    10     return x*m+y+1;
    11 }
    12 void add(int x,int y,int z){
    13     edge[E].nex=head[x];
    14     edge[E].to=y;
    15     edge[E].len=z;
    16     head[x]=E++;
    17     if (E&1)add(y,x,0);
    18 }
    19 bool bfs(){
    20     memset(d,-1,sizeof(d));
    21     q.push(0);
    22     d[0]=0;
    23     while (!q.empty()){
    24         int k=q.front();
    25         q.pop();
    26         for(int i=head[k];i!=-1;i=edge[i].nex)
    27             if ((edge[i].len)&&(d[edge[i].to]<0)){
    28                 d[edge[i].to]=d[k]+1;
    29                 q.push(edge[i].to);
    30             }
    31     }
    32     return d[n*m+1]>=0;
    33 }
    34 int dfs(int k,int s){
    35     if (k>n*m)return s;
    36     for(int &i=work[k];i!=-1;i=edge[i].nex)
    37         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    38             int p=dfs(edge[i].to,min(s,edge[i].len));
    39             if (p){
    40                 edge[i].len-=p;
    41                 edge[i^1].len+=p;
    42                 return p;
    43             }
    44         }
    45     return 0;
    46 }
    47 int dinic(){
    48     int k,ans=0;
    49     while (bfs()){
    50         memcpy(work,head,sizeof(head));
    51         while (k=dfs(0,0x3f3f3f3f))ans+=k;
    52     }
    53     return ans;
    54 }
    55 int main(){
    56     scanf("%d%d",&n,&m);
    57     memset(head,-1,sizeof(head));
    58     for(int i=0;i<n;i++)
    59         for(int j=0;j<m;j++){
    60             scanf("%d",&x);
    61             if ((i+j)&1)add(id(i,j),n*m+1,x);
    62             else add(0,id(i,j),x);
    63             ans+=x;
    64         }
    65     for(int i=0;i<n;i++)
    66         for(int j=0;j<m;j++){
    67             scanf("%d",&x);
    68             if ((i+j)&1)add(0,id(i,j),x);
    69             else add(id(i,j),n*m+1,x);
    70             ans+=x;
    71         }
    72     for(int i=0;i<n;i++)
    73         for(int j=0;j<m;j++){
    74             scanf("%d",&x);
    75             for(int k=0;k<4;k++){
    76                 int tx=i+dx[k],ty=j+dy[k];
    77                 if ((tx<0)||(ty<0)||(tx==n)||(ty==m))continue;
    78                 ans+=x;
    79                 add(id(i,j),id(tx,ty),x);
    80                 add(id(tx,ty),id(i,j),x);
    81             }
    82         }
    83     printf("%d",ans-dinic());
    84 }
    View Code
  • 相关阅读:
    LeetCode485 最大连续1的个数
    LeetCode167 两数之和 II
    js浮点数类型
    js整数类型
    js布尔类型
    js重复赋值 js数据交换 js调式方法
    JavaScript变量
    数据类型分类
    重复赋值 数据交换 查看程序执行结果
    JS注释 JS变量
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11847890.html
Copyright © 2011-2022 走看看