几个样例:

5 5
wCCww
wCC..
..w..
....w
ww..w
Returns: 0

3 3
C.w
...
.C.
Returns: 1

21 20
CC..CCCw.CwC..CC.w.C
C.CCCwCCC.w.w..C.w..
wwww...CC.wC.Cw.CC..
CC..CC.w..w.C..CCCC.
CC.CCC..CwwCCC.wCC..
w.C..wwCC.CC.wwwCC..
.CC.CC..CCC..CC.CC.C
Cw....C.C.CCC...CC..
CC.C..Cww.C.CwwwC..w
wCCww..C...CCCCCCC.w
C.CCw.CC.ww...C.CCww
C.C.C.CCwCC..wCCw.Cw
CCC.C...w..C.wC.wCCw
CC.C..C..CCC.CC.C...
C.ww...CCC..CC...CCC
...CCC.CwwwC..www.C.
wwCCCCC.w.C.C...wCwC
CCwC.CwCCC.C.w.Cw...
C.w.wC.CC.CCC.C.w.Cw
CCw.CCC..C..CC.CwCCw
C.wwwww.CwwCCwwwwwww
Returns: 9

分析:非常好的一道题!

   这道题和bzoj3171非常像.是一类容量表示限制的题,即要求的东西有许多限制,通过限定容量大小来满足这些限制. 因为和容量大小有关,所以这些限制一般为数字上的限制.

   遇到这类题该怎么做呢?

   1.题目肯定会让你求满足条件的情况下的最值.首先要分析得到怎么样才能满足条件,一定要找到数字关系!

   2.容量大小代表数字限制,建一个直观的最大流模型.

   3.拆点,将有花费的操作连成对应的有费用的边.

   如何建呢?

   首先找到初始状态,即所有边都是没有任何费用的. 例如bzoj3171题目中给出的箭头,本题中将所有的轨道变成弯的就是初始状态了. 接着找到需要费用的边. 例如bzoj3171中的更改箭头方向,本题中的将一个弯的轨道变成直的轨道(有弯星人在上面的). 最后检查建出来的图是否满足要求:存在对应关系:满足限制即满流.

   对于这道题而言,每一个空地必须伸出两个轨道,每个点有直的铁轨和弯的铁轨.

   直的铁轨即,一块空地连出两条横向或纵向的轨道。弯的铁轨即,一块空地连出一条横向和一条纵向的轨道。

一个点两种不同的类别,这启示我们拆点分类.对于每一个点拆成两个点,一个是横着的点,伸出两个横着的轨道,一个是竖着的点,伸出两个竖着的轨道.它们都只和相邻的没有障碍的点拆出来的对应点相连,容量为1,费用为0

   有费用的边即同一个点拆出来的两个点,如果这个点上有弯星人,它们之间的费用则为1,否则为0,容量为1.

   那么和源汇的边要怎么处理呢?

   错误的做法:一个点既连源点又连汇点. 显然这样源点会直接通过这个点走到汇点,不行.

   正确的做法是黑白染色!相当于把图看作二分图. 对于图上做网络流,连边的问题通常用这种方法解决.

   事实上也不需要真的dfs去染色,只需要看行数+列数是奇数还是偶数即可.

   最后要先判断是否满流,再来输出解.

   挺好的题,将限制与容量联系起来,是一类较为常见的题型.get到了新姿势:黑白染色建图.

  1. #include <queue>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8. const int maxn = ,dx[] = {,,,-},dy[] = {,-,,},inf = 0x7fffffff;
  9. int n,m,head[maxn],to[maxn * ],nextt[maxn * ],w[maxn * ],cost[maxn * ],tot = ;
  10. int S,T,ans,anss,sum;
  11. int vis[maxn],vis2[maxn],d[maxn];
  12. char s[maxn][maxn];
  13.  
  14. void add(int x,int y,int z,int p)
  15. {
  16. cost[tot] = p;
  17. w[tot] = z;
  18. to[tot] = y;
  19. nextt[tot] = head[x];
  20. head[x] = tot++;
  21.  
  22. cost[tot] = -p;
  23. w[tot] = ;
  24. to[tot] = x;
  25. nextt[tot] = head[y];
  26. head[y] = tot++;
  27. }
  28.  
  29. bool spfa()
  30. {
  31. for (int i = ; i <= T; i++)
  32. d[i] = inf;
  33. memset(vis,,sizeof(vis));
  34. memset(vis2,,sizeof(vis2));
  35. d[S] = ;
  36. vis[S] = ;
  37. queue <int> q;
  38. q.push(S);
  39. while (!q.empty())
  40. {
  41. int u = q.front();
  42. q.pop();
  43. vis[u] = ;
  44. for (int i = head[u];i;i = nextt[i])
  45. {
  46. int v = to[i];
  47. if (w[i] && d[v] > d[u] + cost[i])
  48. {
  49. d[v] = d[u] + cost[i];
  50. if (!vis[v])
  51. {
  52. vis[v] = ;
  53. q.push(v);
  54. }
  55. }
  56. }
  57. }
  58. return d[T] < inf;
  59. }
  60.  
  61. int dfs(int u,int f)
  62. {
  63. if (u == T)
  64. {
  65. ans += d[u] * f;
  66. return f;
  67. }
  68. int res = ;
  69. vis2[u] = ;
  70. for (int i = head[u];i;i = nextt[i])
  71. {
  72. int v = to[i];
  73. if (!vis2[v] && w[i] && d[v] == d[u] + cost[i])
  74. {
  75. int temp = dfs(v,min(f - res,w[i]));
  76. w[i] -= temp;
  77. w[i ^ ] += temp;
  78. res += temp;
  79. if (res == f)
  80. return res;
  81. }
  82. }
  83. return res;
  84. }
  85.  
  86. void dinic()
  87. {
  88. while (spfa())
  89. anss += dfs(S,inf);
  90. }
  91.  
  92. int calc(int x,int y)
  93. {
  94. return (x - ) * m + y;
  95. }
  96.  
  97. int main()
  98. {
  99. scanf("%d%d",&n,&m);
  100. S = n * m * + ;
  101. T = S + ;
  102. for (int i = ; i <= n; i++)
  103. scanf("%s",s[i] + );
  104. for (int i = ; i <= n; i++)
  105. for (int j = ; j <= m; j++)
  106. {
  107. if (s[i][j] == 'w')
  108. continue;
  109. int temp = calc(i,j);
  110. if ((i + j) % == )
  111. {
  112. sum += ;
  113. add(S,calc(i,j),,);
  114. add(S,calc(i,j) + n * m,,);
  115. //横
  116. if (j - > && s[i][j - ] != 'w')
  117. add(calc(i,j),calc(i,j - ),,);
  118. if (j + <= m && s[i][j + ] != 'w')
  119. add(calc(i,j),calc(i,j + ),,);
  120. //竖
  121. if (i - > && s[i - ][j] != 'w')
  122. add(calc(i,j) + n * m,calc(i - ,j) + n * m,,);
  123. if (i + <= n && s[i + ][j] != 'w')
  124. add(calc(i,j) + n * m,calc(i + ,j) + n * m,,);
  125. }
  126. else
  127. {
  128. add(calc(i,j),T,,);
  129. add(calc(i,j) + n * m,T,,);
  130. }
  131. int p = ;
  132. if (s[i][j] == 'C')
  133. p = ;
  134. add(calc(i,j),calc(i,j) + n * m,,p);
  135. add(calc(i,j) + n * m,calc(i,j),,p);
  136. }
  137. dinic();
  138. if (anss != sum)
  139. ans = -;
  140. printf("%d\n",ans);
  141.  
  142. return ;
  143. }

Topcoder SRM570 D1L3 CurvyonRails的更多相关文章

  1. Topcoder SRM570 900 CurvyonRails

    题意:给定一个网格,一些格子是障碍不用管,剩余的格子是城市,你可以修建铁路,铁路的形状可以是直的或者弯的,也就是说可以以这个点为节点连接它四联通的其中两个方块.要求用一个或多个环来覆盖所有城市.对于有 ...

  2. @topcoder - SRM766R1 D1L3@ ShortestMissingSubsequences

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个大小为 G 的字符集,并给定一个长度为 N 的字符串 A ...

  3. @topcoder - 2013TCO3A D1L3@ TrickyInequality

    目录 @description@ @accepted code@ @accepted code@ @details@ @description@ 现有不等式组: \[\begin{cases} x_1 ...

  4. Topcoder口胡记 SRM 562 Div 1 ~ SRM 599 Div 1

    据说做TC题有助于提高知识水平? :) 传送门:https://284914869.github.io/AEoj/index.html 转载请注明链接:http://www.cnblogs.com/B ...

  5. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  6. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  7. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  8. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  9. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

随机推荐

  1. 3.0 zookeeper的集群介绍、搭建、环境、安装

    zookeeper是本身是一种分布式协调服务(英文意思动物园园长因为Hadoop就是一个动物园,storm.hadoop.kafkaka.hbaser都是基于zookeeper开发的) 原理:Zook ...

  2. JavaScript学习笔记(一)——JS速览

    第一章 JS速览 1 限制时间处理事件 <script> setTomeout(wakeUpUser,5000); function wakeUpUser() { alert(" ...

  3. 与面试官谈笑风生 | Python面向对象之访问控制

    Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装.所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念 ...

  4. Friends and Cookies(思维)

    Abood's birthday has come, and his n friends are aligned in a single line from 1 to n, waiting for t ...

  5. Scrum立会报告+燃尽图(十一月二十四日总第三十二次):视频剪辑

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  6. 博弈---ZOJ 3057 Beans Game(DP博弈)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3057 有豆类三个桩.TT和DD挑选任意数量的豆子从任何两堆轮流任何桩或相同 ...

  7. 倒计时60s 代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. MySQL 基于mysqldump备份工具实战演练

    前言: 细节提示:先执行 show global variables like 'log_bin';看看log_bin的值,如果服务器变量log_bin的值为OFF,需要修改my.cnf配置文件,将l ...

  9. 这套C#编码规范写不错

    自己总结的C#编码规范--1.命名约定篇:http://www.cnblogs.com/luzhihua55/p/CodingConventions1.html 自己总结的C#编码规范--2.命名选择 ...

  10. 使用nginx反向代理时,如何正确获取到用户的真实ip

    在记录日志的的时候,获取用户的信息,比如用户的ip,浏览器等等信息是十分重要的. 但是在使用nginx反向代理的时候,可能经过转发无法获取到用户的真实的ip, 在此情况下需要配置nginx,让其在转发 ...