题目链接:

option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接

题意:

给定n*n的棋盘,

能够在'.'上摆 象棋中的车(X是墙壁)

使得随意两个车都不能互相攻击到

问:最多能摆多少个车。

思路:

二分匹配

1、若没有X。那么做法就是 X点集为行,Y点集为列,对于图上的每一个点所在的行和列(x,y) 建一条边 x->y

2、有了X,那么对于每一个点所在的上方能接触到的X必须各不同样。所以给每一个X标号,第一个X标记成n+1

3、这样X点集就是行(1-n) 和 n+1-siz (siz是X的个数)

4、对于每一个点,上方能接触到的近期的X作为列,右方能接触到的近期的Y作为行,建一条边 X->Y

而处理每一个点上方能接触到的近期的X就是一个dp。右方也是相同处理。

然后跑个二分匹配就好。

  1.  
  1. <pre name="code" class="cpp">#pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include<bits/stdc++.h>
  3. template <class T>
  4. inline bool rd(T &ret) {
  5. char c; int sgn;
  6. if(c=getchar(),c==EOF) return 0;
  7. while(c!='-'&&(c<'0'||c>'9')) c=getchar();
  8. sgn=(c=='-')?-1:1;
  9. ret=(c=='-')?0:(c-'0');
  10. while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
  11. ret*=sgn;
  12. return 1;
  13. }
  14. template <class T>
  15. inline void pt(T x) {
  16. if (x <0) {
  17. putchar('-');
  18. x = -x;
  19. }
  20. if(x>9) pt(x/10);
  21. putchar(x%10+'0');
  22. }
  23. using namespace std;
  24. const int N = 10105;
  25. struct Edge{
  26. int to, nex;
  27. }edge[N*2];
  28. int head[N], edgenum;
  29. void init(){memset(head, -1, sizeof head); edgenum = 0;}
  30. void add(int u, int v){
  31. Edge E = {v, head[u]};
  32. edge[edgenum] = E;
  33. head[u] = edgenum++;
  34. }
  35. int lef[N], pn;
  36. int tim, T[N];
  37.  
  38. bool match(int x){
  39. for(int i=head[x]; ~i; i=edge[i].nex)
  40. {
  41. int v = edge[i].to;
  42. if(T[v] != tim)
  43. {
  44. T[v] = tim;
  45. if(lef[v] == -1 || match( lef[v] )) //match(lef[v]) : 原本连接v的X集点 lef[v] 能不能和别人连。假设能 则v这个点就空出来和x连
  46. {
  47. lef[v] = x;
  48. return true;
  49. }
  50. }
  51. }
  52. return false;
  53. }
  54.  
  55. int solve(){
  56. int ans = 0;
  57. memset(lef, -1, sizeof(lef));
  58. for(int i = 1; i<= pn; i++)//X集匹配。X集点标号从 1-pn 匹配边是G[左点].size()
  59. {
  60. tim++;
  61. if( match( i ) ) ans++;
  62. }
  63. return ans;
  64. }
  65. int n, siz, s[105][105], l[105][105], mp[105][105];
  66. char str[105];
  67. void input(){
  68. siz = n;
  69. for(int i = 1; i <= n; i++)
  70. {
  71. scanf("%s", str+1);
  72. for(int j = 1; j <= n; j++){
  73. if(str[j] == 'X')
  74. mp[i][j] = ++siz;
  75. else
  76. mp[i][j] = 0;
  77. }
  78. }
  79. }
  80. void build(){
  81. for(int i = 1; i <= n; i++)
  82. s[0][i] = i;
  83. for(int i = 1; i <= n; i++)
  84. for(int j = 1; j <= n; j++)
  85. if(mp[i][j])
  86. s[i][j] = mp[i][j];
  87. else
  88. s[i][j] = s[i-1][j];
  89. for(int i = 1; i <= n; i++)
  90. l[i][n+1] = i;
  91. for(int i = n; i; i--)
  92. {
  93. for(int j = 1; j <= n; j++)
  94. if(mp[j][i])
  95. l[j][i] = mp[j][i];
  96. else
  97. l[j][i] = l[j][i+1];
  98. }
  99. init();
  100. pn = siz;
  101. for(int i = 1; i <= n; i++)
  102. for(int j = 1; j <= n; j++)
  103. if(mp[i][j] == 0)
  104. add(l[i][j+1], s[i-1][j]);
  105. }
  106. int main(){
  107. tim = 1; memset(T, 0, sizeof T);
  108. while(cin>>n){
  109. input();
  110. build();
  111. cout<<solve()<<endl;
  112. }
  113. return 0;
  114. }
  115. /*
  116. 5
  117. X....
  118. X....
  119. ..X..
  120. .X...
  121. ....X
  122.  
  123. 3
  124. .X.
  125. XXX
  126. XXX
  127.  
  128. 3
  129. .X.
  130. X.X
  131. XXX
  132.  
  133. 3
  134. .X.
  135. X.X
  136. X.X
  137.  
  138. 3
  139. .X.
  140. X.X
  141. .X.
  142. 3
  143. XXX
  144. XXX
  145. XXX
  146. 15
  147. XXXXXXXXXXXXXXX
  148. XXXXXXXXXXXXXXX
  149. XXXXXXXXXXXXXXX
  150. XXXXXXXXXXXXXXX
  151. XXXXXXXXXXXXXXX
  152. XXXXXXXXXXXXXXX
  153. XXXXXXXXXXXXXXX
  154. XXXXXXXXXXXXXXX
  155. XXXXXXXXXXXXXXX
  156. XXXXXXXXXXXXXXX
  157. XXXXXXXXXXXXXXX
  158. XXXXXXXXXXXXXXX
  159. XXXXXXXXXXXXXXX
  160. XXXXXXXXXXXXXXX
  161. XXXXXXXXXXXXXXX
  162.  
  163. */
  1.  

UVALive 6525 Attacking rooks 二分匹配 经典题的更多相关文章

  1. UVaLive 6525 Attacking rooks (二分图最大匹配)

    题意:给定一个 n * n的图,X是卒, . 是空位置,让你放尽量多的车,使得他们不互相攻击. 析:把每行连续的 . 看成X集体的一个点,同理也是这样,然后求一个最大匹配即可. 代码如下: #prag ...

  2. ZOJ 1654 二分匹配基础题

    题意: 给你一副图, 有草地(*),空地(o)和墙(#),空地上可以放机器人, 机器人向上下左右4个方向开枪(枪不能穿墙),问你在所有机器人都不相互攻击的情况下能放的最多的机器人数. 思路:这是一类经 ...

  3. HNU13028Attacking rooks (二分匹配,一行变多行,一列变多列)

    Attacking rooks Time Limit: 20000ms, Special Time Limit:50000ms, Memory Limit:65536KB Total submit u ...

  4. POJ 1469 ZOJ1140 二分匹配裸题

    很裸,左点阵n,右点阵m 问最大匹配是否为n #include <cstdio> #include <cstring> #include <vector> usin ...

  5. COURSES 赤裸裸的二分匹配大水题

    COURSES 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include ...

  6. UVA5874 Social Holidaying 二分匹配

    二分匹配简单题,看懂题意,建图比较重要. #include<stdio.h> #include<string.h> #define maxn 1100 int map[maxn ...

  7. hdu 1068 Girls and Boys (二分匹配)

    Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. poj2239 poj1274【二分匹配】

    题意: 就是尽可能的选多的课 思路: 把课程和上课的时间看作二分图 跑一跑二分匹配就好了 #include<iostream> #include<cstdio> #includ ...

  9. HDU 3861 The King’s Problem(tarjan缩点+最小路径覆盖:sig-最大二分匹配数,经典题)

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. Remoting 的“传递的引用”理解

    WCf是集大成者,具有其他微软的很多技术,其中分布式上很多借助于Remoting,所以研究一下Remoting有助于理解WCF 提到Remoting就不得不涉及到MarshalByRefObject这 ...

  2. __dopostback的用法 . 编辑

    在.NET中,所有的服务器控件提交到服务器的时候,都会调用__doPostBack这个函数,所以灵活运用这个函数对于我们的帮助还是很大的. 比如,在我们写程序的时候经常会需要动态的生成一些控件,最简单 ...

  3. jQuery 小知识点(插件)

    1.jQuery插件小知识点: 估计很多人都没弄明白下面的东西,特从网络上搜索了下面的知识,自己以后用起来也比较方便: $.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例 ...

  4. IMAGE_SECTION_HEADER

    typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAdd ...

  5. Flume笔记--source端监听目录,sink端上传到HDFS

    官方文档参数解释:http://flume.apache.org/FlumeUserGuide.html#hdfs-sink 需要注意:文件格式,fileType=DataStream 默认为Sequ ...

  6. ubuntu下怎么显示右上角的小键盘

    Ubuntu右上角小键盘不见了解决方法: ibus输入法的图标经常消失,输入中文时很不方便,重启一下ibus!   按Ctrl+ALT+T 快捷键打开终端,   输入:   1.killall ibu ...

  7. hdu 2992 Hotel booking

    http://acm.hdu.edu.cn/showproblem.php?pid=2992 #include <cstdio> #include <cstring> #inc ...

  8. rsync同步目录及同步文件

    最简单的只读同步工作. 一,服务端的配置 1,安装rsync(阿里云默认已有此程序) 略 2,生成文件rsyncd.conf,内容如下: #secrets file = /etc/rsyncd.sec ...

  9. JVM虚拟机栈和本地方法栈溢出测试

    弄JAVA,那JVM,JAVA语法,JDK库,JAVAEE,流行框架是一个都不能少,才可以有全局感的. JVM高级特性这书,看得差不多了.慢慢实践. /** * * *VM Args: -Xms20m ...

  10. 51单片机C语言学习笔记7:关于.c文件和.h文件

    1)h文件作用 1 方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明: 2 提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h). 2)h文件里应该有什么 ...