• bzoj2132【圈地计划】


    题面

    思路:

    一开始以为和为了博多一样,两边连一样的,后来发现中间连负边的话根本不会割,即割断两块收益为负,所以WA的起飞……

        正解是先黑白染色,每个点和它周围的点连边方式不同。对于黑点AS-->A表示商业区的价值,A-->T表示工业区的价值,白点相反,对于相邻的情况,边权表示相邻的价值和,这样割断相当于选择同一用途,代价为正

      1 #include <map>
      2 #include <set>
      3 #include <cmath>
      4 #include <queue>
      5 #include <stack>
      6 #include <cstdio>
      7 #include <string>
      8 #include <vector>
      9 #include <cstring>
     10 #include <complex>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 #define rg register
     15 #define ll long long
     16 using namespace std;
     17 
     18 inline int gi()
     19 {
     20     rg int r = 0; rg bool b = 1; rg char c = getchar();
     21     while ((c < '0' || c > '9') && c != '-') c = getchar();
     22     if (c == '-') b = 0;
     23     while (c >= '0' && c <= '9') { r = (r << 1) + (r << 3) + c - '0', c = getchar(); }
     24     if (b) return r; return -r;
     25 }
     26 
     27 const int inf = 2e8+5, N = 105, M = 5e5+1;
     28 int n,m,num,S,T;
     29 int dx[]={0,0,-1,1},dy[]={-1,1,0,0},dep[N*N],f[N*N],c[N][N];
     30 bool col[N][N];
     31 queue <int> q;
     32 struct Edge
     33 {
     34     int to,nx,cap;
     35 }eg[M];
     36 
     37 inline void add(int x,int y,int z)
     38 {
     39     eg[++num]=(Edge){y,f[x],z}, f[x]=num;
     40 }
     41 
     42 inline void link(int x,int y,int z)
     43 {
     44     add(x,y,z), add(y,x,0);
     45 }
     46 
     47 inline int dfs(int o,int flow)
     48 {
     49     if (o == T || !flow) return flow;
     50     rg int to,cap,fl,tmp,i;
     51     fl=0;
     52     for (i=f[o]; i; i=eg[i].nx)
     53         {
     54             to=eg[i].to, cap=eg[i].cap;
     55             if (dep[o] != dep[to]-1 || cap <= 0)
     56                 continue;
     57             tmp=dfs(to,min(flow,cap));
     58             if (!tmp) continue;
     59             fl+=tmp, flow-=tmp;
     60             eg[i].cap-=tmp, eg[i^1].cap+=tmp;
     61             if (!flow) break;
     62         }
     63     if (!fl) dep[o]=0;
     64     return fl;
     65 }
     66 
     67 inline int bfs()
     68 {
     69     memset(dep,0,sizeof(dep));
     70     rg int o,to,cap,i;
     71     q.push(S); dep[S]=1;
     72     while (!q.empty())
     73         {
     74             o=q.front(), q.pop();
     75             for (i=f[o]; i; i=eg[i].nx)
     76                 {
     77                     to=eg[i].to, cap=eg[i].cap;
     78                     if (dep[to] || cap <= 0)
     79                         continue;
     80                     dep[to]=dep[o]+1, q.push(to);
     81                 }
     82         }
     83     return dep[T];
     84 }
     85 
     86 inline int dinic()
     87 {
     88     rg int flow;
     89     flow=0;
     90     while (bfs()) flow+=dfs(S,inf);
     91     return flow;
     92 }
     93 
     94 int main()
     95 {
     96     rg int i,j,k,x,y,dis,ans;
     97     n=gi(), m=gi();
     98     ans=S=0, T=n*m+1, num=1;
     99     for (i=1; i<=n; ++i)
    100         for (j=1; j<=m; ++j)
    101             if ((i+j)&1)
    102                 col[i][j]=1;
    103     for (i=1; i<=n; ++i)
    104         for (j=1; j<=m; ++j)
    105             {
    106                 dis=gi(), ans+=dis;
    107                 if (col[i][j])
    108                     link(S,(i-1)*m+j,dis);
    109                 else
    110                     link((i-1)*m+j,T,dis);
    111             }
    112 
    113     for (i=1; i<=n; ++i)
    114         for (j=1; j<=m; ++j)
    115             {
    116                 dis=gi(), ans+=dis;
    117                 if (col[i][j])
    118                     link((i-1)*m+j,T,dis);
    119                 else
    120                     link(S,(i-1)*m+j,dis);
    121             }
    122     for (i=1; i<=n; ++i) for (j=1; j<=m; ++j) c[i][j]=gi();
    123     for (i=1; i<=n;++i)
    124         for (j=1; j<=m; ++j)
    125             {
    126                 if (!col[i][j]) continue;
    127                 for (k=0; k<4; ++k)
    128                     {
    129                         x=i+dx[k], y=j+dy[k];
    130                         if (x > n || x < 1 || y > m || y < 1)
    131                             continue;
    132                         add((i-1)*m+j,(x-1)*m+y,c[i][j]+c[x][y]);
    133                         add((x-1)*m+y,(i-1)*m+j,c[i][j]+c[x][y]);
    134                         ans+=c[i][j]+c[x][y];
    135                     }
    136             }
    137     printf("%d
    ",ans-dinic());
    138     return 0;
    139 }
  • 相关阅读:
    Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation '=' 一个解决办法(转载)
    mysql limit用法
    preparedStatement一个小技巧
    两个简单的压力测试代码。
    cookie实现session机制
    java.util.properties用法
    数据库是否使用外键,及视图,索引,存储过程的一些说明(zz)
    某项目要调用现有的100多个DLL 二 最最简单原型的思考
    面试题:红绿灯
    一个简单的封装 .net的日志功能
  • 原文地址:https://www.cnblogs.com/y142857/p/7229794.html
Copyright © 2020-2023  润新知