以防万一,题目原文和链接均附在文末。那么先是题目分析:

【一句话题意】

给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔。

【题目分析】

这题本来在搜索专题里出现的..这回又在二分查找匹配专题出现了..所以当然要按照二分匹配的方法解而不是爆搜(虽然爆搜能过)。
问题主要就是如何缩点建图。为了使得blockhouse不能互相攻击,那么使用每行的相邻的点缩点,每列的相邻的点缩点,连边的条件就是两个点存在有相交的部分,最后这两组点求最大匹配就行了。

【算法流程】

应该这题也能算是标准题了吧。缩点,建图,hungary匈牙利算法求解,输出答案。完事儿了。
匈牙利算法以及二分最大匹配的相关内容这里就不说了。。

下面的代码简单说明,本来的aleft和aright名字叫left和right,后来发现和STL的东西冲突了。。
fill的宏定义有更科学的方法,这里就只是单纯的抹0。以及for each是从1到n而不是从0到n。
因为习惯问题,数组是从1算起的。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <queue>
  6. #include <algorithm>
  7. #include <vector>
  8. #define each(i,n) (int i=1;i<=(n);++i)
  9. #define fill(arr) memset(arr,0,sizeof(arr))
  10. #define INF 0x3f3f3f3f
  11.  
  12. char map[][];
  13. char aleft[][];
  14. char aright[][];
  15. int l[], r[], lCnt, rCnt;
  16. bool graph[][];
  17. bool vis[];
  18.  
  19. using namespace std;
  20.  
  21. int dfs(int left) {
  22. for each(right,rCnt) {
  23. //left到right有路且没遍历过
  24. if(graph[left][right] && !vis[right]) {
  25. vis[right] = true;
  26. //若right还没匹配过或跟right匹配的点找到另一个相匹配的点
  27. //(则right就可以跟left匹配)
  28. if(r[right]==- || dfs(r[right])) {
  29. r[right] = left;
  30. l[left] = right;
  31. //printf("(%d,%d)\n",left,right);
  32. return ;
  33. }
  34. }
  35. }
  36. return ;
  37. }
  38.  
  39. int hungary() {
  40. int ans = ;
  41. memset(l,-,sizeof(l));
  42. memset(r,-,sizeof(r));
  43. for each(i,lCnt) { //row point cnt
  44. if(l[i] == -) {
  45. fill(vis);
  46. ans += dfs(i);
  47. }
  48. }
  49. return ans;
  50. }
  51.  
  52. int main() {
  53.  
  54. int n;
  55. char buffer[];
  56. while(gets(buffer)) {
  57. //proc input
  58. if (buffer[] == '') break;
  59. sscanf(buffer,"%d",&n);
  60. for each(line,n) {
  61. gets(buffer);
  62. for each(col,n) {
  63. map[line][col] = buffer[col-];
  64. }
  65. }
  66. //create grapth [ Marking up Points ]
  67. fill(aleft);
  68. fill(aright);
  69. lCnt = ;
  70. int pre = ;
  71. for each(row,n) {
  72. for each(col,n) {
  73. if(map[row][col]=='X') {
  74. if(pre==lCnt) ++lCnt;
  75. continue;
  76. }
  77. aleft[row][col] = lCnt;
  78. pre = lCnt;
  79. }
  80. if(pre==lCnt) ++lCnt;
  81. }
  82. lCnt = pre;
  83. rCnt = ;
  84. pre = ;
  85. for each(col,n) {
  86. for each(row,n) {
  87. if(map[row][col]=='X') {
  88. if(pre==rCnt) ++rCnt;
  89. continue;
  90. }
  91. aright[row][col] = rCnt;
  92. pre = rCnt;
  93. }
  94. if(pre==rCnt) ++rCnt;
  95. }
  96. rCnt = pre;
  97. //create grapth [ Shrinking Points ]
  98. fill(graph);
  99. for each(row,n) {
  100. for each(col,n) {
  101. if(map[row][col]=='.')
  102. graph[aleft[row][col]][aright[row][col]] = true;
  103. }
  104. }
  105. //doWork
  106. printf("%d\n",hungary());
  107. }
  108.  
  109. }

题目链接:Fire Net(HDU 1045)

题目属性:二分图最大匹配 (如果愿意你可以去爆搜..)

相关题目:2444 1083 1281 2819 2389 4185 poj3020 ...

题目原文:
【desc】
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.

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.

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.

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.

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.

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.
【In】
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.
【Out】
For each test case, output one line containing the maximum number of
blockhouses that can be placed in the city in a legal configuration.

【SampIn】
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
【SampOut】
5
1
5
2
4

HDU 1045(Fire Net)题解的更多相关文章

  1. HDOJ(HDU).1045 Fire Net (DFS)

    HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...

  2. hdu 1045 Fire Net(最小覆盖点+构图(缩点))

    http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS     Memory Limit:32768KB   ...

  3. HDU 1045 Fire Net 状压暴力

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)  ...

  4. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

  5. HDU 1045 Fire Net(dfs,跟8皇后问题很相似)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)   ...

  6. HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】

    Fire Net Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  7. HDU 1045 Fire Net 二分图建图

    HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...

  8. HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  9. hdu 1045 Fire Net(二分图)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意为给定一个最大为4*4的棋盘,棋盘可以放置堡垒,处在同一行或者同一列的堡垒可以相互攻击, ...

随机推荐

  1. ng-class用法

    在angular中为我们提供了3种方案处理class: 1:scope变量绑定.这种方案不推荐,因为scope里最好处理业务逻辑,不去管渲染的事.2:字符串数组形式.3:对象key/value处理. ...

  2. JS 之 innerHTML

    定义和用法 innerHTML 属性用于设置或返回指定标签之间的 HTML 内容. 语法 Object.innerHTML = "HTML";// 设置 var html = Ob ...

  3. 自己动手打造html5星际迷航!

    学习html5的canvas第三天,觉得还没过瘾,转眼就忘,于是趁着有空,准备弄个小游戏来玩!游戏应该需要注意性能,还有一些逻辑需要斟酌,我想还需要用户可修改性,也就是用户配置.好,开始我们简单但有趣 ...

  4. FireDAC

    http://docs.embarcadero.com/products/rad_studio/firedac/frames.html Access: http://docwiki.embarcade ...

  5. python笔记之Cmd模块

    python笔记之Cmd模块 Cmd类型提供了一个创建命令行解析器的框架,默认情况下,它使用readline来进行交互式操作.命令行编辑和命令完成. 使用cmd创建的命令行解释器循环读取输入的所有行并 ...

  6. 循环-10. 求序列前N项和*

    /* * Main.c * C10-循环-10. 求序列前N项和 * Created on: 2014年7月30日 * Author: Boomkeeper *******部分通过******* */ ...

  7. XML的Schema约束

    XSD文档至少要包含:schema根元素和XML模式命名空间的定义.元素定义.需要注意的是XSD中必须定义一个且只能定义一个schema根元素,根元素中包括模式的约束,XML模式命名空间的定义,其他命 ...

  8. 32位程序调用Oracle11gR2数据库libclntsh.so失败

    [问题描述]32位程序调用Oracle11gR2数据库的libclntsh.so库时会返回失败. [问题原因]32位程序只能调用32位的Oracle客户端实例包,而R2数据库默认安装完毕后是没有lib ...

  9. (七)boost库之单例类

    (七)boost库之单例类 一.boost.serialzation的单件实现 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一 ...

  10. 栈的C数组实现

    栈是一种先进后出的数据结构.栈的基本操作包括:入栈,出栈,初始化栈,清空栈,遍历栈. C代码如下: #include <stdio.h> #define MaxSize 20 typede ...