zoukankan      html  css  js  c++  java
  • hdu 1045 二分匹配,x、y缩成一点

    1. /**********************************************************************************
    2. hdu 1045 Fire Net
    3. 这题意思是给出一张图,图中'X'表示wall,'.'表示空地,可以放置blockhouse
    4. 同一条直线上只能有一个blockhouse,除非有wall隔开,问在给出的图中
    5. 最多能放置多少个blockhouse
    6. 二分匹配,别人都说水题,但我没看出它是二分图匹配
    7. 这题是把原始图分别按行和列缩点
    8. 建图:横竖分区。先看每一列,同一列相连的空地同时看成一个点,显然这
    9. 样的区域不能够同时放两个点。这些点作为二分图的X部。同理在对所有的
    10. 行用相同的方法缩点,作为Y部。
    11. 连边的条件是两个区域有相交部分(即'.'的地方)。最后求最大匹配就是答案。
    12. **********************************************************************************/
    13. #include <stdio.h>
    14. #include <string.h>
    15. #define N 8
    16. int cnt_row, cnt_col;
    17. int row[N][N], col[N][N], r[N], c[N];
    18. char map[N][N];
    19. bool path[N][N], vis[N];
    20. int dfs(int rr)
    21. {
    22. for(int i = 0; i < cnt_col; ++i)
    23. { //rr到i有路径 且 i没遍历过
    24. if(path[rr][i] && vis[i] == false)
    25. {
    26. vis[i] = true;
    27. if(c[i] == -1 || dfs(c[i]))//若 i 还没匹配过或 跟i
    28. { //匹配的点找到另一个相匹配的点(则i 就可以跟rr匹配)
    29. c[i] = rr;
    30. return 1;
    31. }
    32. }
    33. }
    34. return 0;
    35. }
    36. int maxmatch()
    37. {
    38. int ans = 0;
    39. memset(r, -1, sizeof(r));
    40. memset(c, -1, sizeof(c));
    41. for(int i = 0; i < cnt_row; ++i)
    42. {
    43. if(dfs(i) )
    44. {
    45. memset(vis, false, sizeof(vis));
    46. ans ++;
    47. }
    48. }
    49. return ans;
    50. }
    51. int main()
    52. {
    53. int n;
    54. //freopen("read.txt", "r", stdin);
    55. while(scanf("%d", &n), n)
    56. {
    57. for(int i = 0; i < n; ++i)
    58. {
    59. char tp[100];
    60. scanf("%s", tp);
    61. for(int j = 0; j < n; ++j)
    62. map[i][j] = tp[j];
    63. }
    64. memset(row, -1, sizeof(row));
    65. memset(col, -1, sizeof(col));
    66. cnt_row = cnt_col = 0;
    67. for(int i = 0; i < n; ++i)
    68. {
    69. for(int j = 0; j < n; ++j)
    70. {
    71. if(map[i][j] == '.' && row[i][j] == -1)
    72. { //横向缩点
    73. for(int k = j; map[i][k] == '.' && k < n; ++k)
    74. row[i][k] = cnt_row; //给相同的区域标记同一个数字
    75. cnt_row++;
    76. }
    77. if(map[j][i] == '.' && col[j][i] == -1)
    78. { //纵向缩点
    79. for(int k = j; map[k][i] == '.' && k < n; ++k)
    80. col[k][i] = cnt_col; //给相同的区域标记同一个数字
    81. cnt_col++;
    82. }
    83. }
    84. }
    85. memset(path, false, sizeof(path));
    86. for(int i = 0; i < n; ++i)
    87. for(int j = 0; j < n; ++j)
    88. if(map[i][j] == '.') //连边,'.'的地方即为缩点后的 行和列的交点
    89. path[ row[i][j] ][ col[i][j] ] = true;
    90. printf("%d ", maxmatch()); //二分图匹配
    91. }
    92. return 0;
    93. }
    94. /*****************************************************************************************************************
    95. Problem Description
    96. Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.
    97. A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.
    98. Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.
    99. The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.
    100. The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.
    101. Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.
    102. Input
    103. The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a '.' indicating an open space and an uppercase 'X' indicating a wall. There are no spaces in the input file.
    104. Output
    105. For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.
    106. Sample Input
    107. 4
    108. .X..
    109. ....
    110. XX..
    111. ....
    112. 2
    113. XX
    114. .X
    115. 3
    116. .X.
    117. X.X
    118. .X.
    119. 3
    120. ...
    121. .XX
    122. .XX
    123. 4
    124. ....
    125. ....
    126. ....
    127. ....
    128. 0
    129. Sample Output
    130. 5
    131. 1
    132. 5
    133. 2
    134. 4
    135. **********************************************************************************************************/





    附件列表

    • 相关阅读:
      01-文件系统
      适配器模式,新老系统兼容
      01-Entity FrameWork如何控制数据的变化
      .Net实战之反射操作篇
      .Net实战之反射相关类之间的人体经络关系
      .Net实战之反射外卖计费
      [转]UINavigationController 返回的方法汇总
      [转]AFNetWorking使用笔记
      vue----子组件引用vux popup mask遮罩在最上层解决办法 z-index问题
      vue系列---vue项目(已安装vuex)中引入jquery
    • 原文地址:https://www.cnblogs.com/sober-reflection/p/4abef9c17087790d18b2a97770d5953c.html
    Copyright © 2011-2022 走看看