zoukankan      html  css  js  c++  java
  • SRM 558 SurroundingGame

    题意:

    给定一个网格,每个网格有选取代价和占据收益。每个点被占据,需要满足以下两个条件至少一个条件:1.被选取  2.邻近方格都被选取(有公共边被称为邻近)  不一定要占据所有方格,求最大收益。

    输入说明
    第一行两个数 n,m(n,m ≤ 20),表示矩形的长和宽。
    接下来 n 行,每行是 m 个字符组成的字符串,描述投资的花费。
    接下来 n 行,每行是 m 个字符组成的字符串,表示该格子的收益。
    花费和收益按照一种奇葩的方式给出:
    字符

    ‘0’-’9’
    0-9
    ‘a’-’z’
    10-35
    ‘A’-’Z’
    36-61
    输出说明
    一个数,表示收益的和减去投资的和的最大值。
    样例 1
    2 2
    21
    12
    21
    12
    答案:4
    样例 2
    2 2
    ZZ
    ZZ
    11
    11
    答案: 0
    样例 3
    3 3
    XXX
    XXX
    XXX
    aaa
    aZa
    aaa
    答案: 2
    样例 4
    2 4
    asam
    atik
    123A
    45BC
    答案: 71
    样例 5
    98
    IIIIIIII
    IIWWWWII
    IIWIIIII
    IIWIIIII
    IIWWWWII
    IIIIIWII
    IIIIIWII
    IIWWWWII
    IIIIIIII
    IIIIIIII
    II0000II
    II0II0II
    II0II0II
    II0000II
    II0II0II
    II0II0II
    II0000II
    IIIIIIII
    答案: 606

    先黑白染色

    源点S点连白点,汇点T点连黑点

    现将所有利润加起来,显然要减去一部分花费和利润

    我们求最小的使利润合法的要减去一部分花费和利润

    然后转化为求最小割,设收益边和花费边

    首先考虑几种情况

    1.保留一个点的花费边,保留收益边(即不投资拿到利润)

    那么此刻如果相邻有点没有割掉花费边,那么就会有流

    2.割掉一个花费边,保留收益边(投资一个点)

    3.割掉一个收益边,保留花费边(不投资该点)

    只考虑前2中情况我们可以建出:

    考虑第3种情况:

    因为放弃这个格子的收益,代表着相邻的格子的收益必须要靠它自己的花费

    于是有了如下建图

    图片转自ZYYS

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<queue>
      7 using namespace std;
      8 struct Node
      9 {
     10   int next,to,cap;
     11 }edge[200001];
     12 int head[6001],num=1,inf=1e9,S,T,dist[6001],n,m,a[51][51],b[51][51],ans,tot,pre[51][51],nxt[51][51],col[51][51];
     13 char s1[51][51],s2[51][51];
     14 void add(int u,int v,int cap)
     15 {
     16   num++;
     17   edge[num].next=head[u];
     18   head[u]=num;
     19   edge[num].to=v;
     20   edge[num].cap=cap;
     21   num++;
     22   edge[num].next=head[v];
     23   head[v]=num;
     24   edge[num].to=u;
     25   edge[num].cap=0;
     26 }
     27 bool bfs()
     28 {int i;
     29   queue<int>Q;
     30   for (i=S;i<=T;i++)
     31     dist[i]=-1;
     32   dist[S]=0;
     33   Q.push(S);
     34   while (Q.empty()==0)
     35     {
     36       int u=Q.front();
     37       Q.pop();
     38       for (i=head[u];i;i=edge[i].next)
     39     {
     40       int v=edge[i].to;
     41       if (edge[i].cap==0||dist[v]!=-1) continue;
     42       dist[v]=dist[u]+1;
     43       Q.push(v);
     44     }
     45     }
     46   if (dist[T]==-1) return 0;
     47   return 1;
     48 }
     49 int dfs(int x,int flow,int des)
     50 {int i;
     51   if (x==des)  return flow;
     52   if (flow<=0) return 0;
     53   int res=0,tmp;
     54   for (i=head[x];i;i=edge[i].next)
     55     {
     56       int v=edge[i].to;
     57       if (dist[v]==dist[x]+1&&edge[i].cap)
     58     {
     59       tmp=dfs(v,min(edge[i].cap,flow-res),des);
     60       edge[i].cap-=tmp;
     61       edge[i^1].cap+=tmp;
     62       res+=tmp;
     63       if (res==flow) return res;
     64     }
     65     }
     66   return res;
     67 }
     68 int Maxflow()
     69 {
     70   int as=0;
     71   while (bfs())
     72     {
     73       int a=0;
     74       while (a=dfs(S,inf,T)) as+=a;
     75     }
     76   return as;
     77 }
     78 int main()
     79 {int i,j;
     80   cin>>n>>m;
     81   for (i=0;i<n;i++)
     82     {
     83       scanf("%s",s1[i]);
     84     }
     85   for (i=0;i<n;i++)
     86     {
     87       scanf("%s",s2[i]);
     88     }
     89   for (i=1;i<=n;i++)
     90     {
     91       for (j=1;j<=m;j++)
     92     {
     93       if (s1[i-1][j-1]>='0'&&s1[i-1][j-1]<='9')
     94         a[i][j]=s1[i-1][j-1]-'0';
     95       else if (s1[i-1][j-1]>='a'&&s1[i-1][j-1]<='z')
     96         a[i][j]=s1[i-1][j-1]-'a'+10;
     97       else a[i][j]=s1[i-1][j-1]-'A'+36;
     98     }
     99     }
    100     for (i=1;i<=n;i++)
    101     {
    102       for (j=1;j<=m;j++)
    103     {
    104       if (s2[i-1][j-1]>='0'&&s2[i-1][j-1]<='9')
    105         b[i][j]=s2[i-1][j-1]-'0';
    106       else if (s2[i-1][j-1]>='a'&&s2[i-1][j-1]<='z')
    107         b[i][j]=s2[i-1][j-1]-'a'+10;
    108       else b[i][j]=s2[i-1][j-1]-'A'+36;
    109       ans+=b[i][j];
    110     }
    111     }
    112     S=1;tot=1;
    113     for (i=1;i<=n;i++)
    114       {
    115     for (j=1;j<=m;j++)
    116       {
    117         pre[i][j]=++tot;nxt[i][j]=++tot;
    118         col[i][j]=(i+j)&1;
    119       }
    120       }
    121     T=++tot;
    122     for (i=1;i<=n;i++)
    123       {
    124     for (j=1;j<=m;j++)
    125       {
    126         if (col[i][j]==0)
    127           {
    128         add(S,pre[i][j],a[i][j]);
    129         add(pre[i][j],nxt[i][j],b[i][j]);
    130         if (i-1)
    131           add(pre[i][j],nxt[i-1][j],inf),add(nxt[i][j],pre[i-1][j],inf);
    132         if (i<n)
    133           add(pre[i][j],nxt[i+1][j],inf),add(nxt[i][j],pre[i+1][j],inf);
    134         if (j-1)
    135           add(pre[i][j],nxt[i][j-1],inf),add(nxt[i][j],pre[i][j-1],inf);
    136         if (j<m)
    137           add(pre[i][j],nxt[i][j+1],inf),add(nxt[i][j],pre[i][j+1],inf);
    138           }
    139         else
    140           {
    141         add(pre[i][j],T,a[i][j]);
    142         add(nxt[i][j],pre[i][j],b[i][j]);        
    143           }
    144       }
    145       }
    146     cout<<ans-Maxflow();
    147 }
  • 相关阅读:
    ASP.NET MVC 学习: 视图
    翻译:ASP.NET MVC Example Application over Northwind with Entity Framework
    主流web2.0网站的配色参考方案
    jQuery1.2选择器
    ASP.NET MVC URL Routing 学习
    [转]关于DOM元素定位属性的深入学习
    ASP.NET MVC : Action过滤器(Filtering)
    【翻译】使用ASP.NET MVC 和LINQ建立一个简单的博客 Part 3
    Windows 8开发者训练营第一日来自现场的图片报道
    从数据到信息到决策
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8619496.html
Copyright © 2011-2022 走看看