Battle ships

Problem Description
Dear contestant, now you are an excellent navy commander, who is responsible of a tough mission currently.
Your fleet unfortunately encountered an enemy fleet near the South Pole where the geographical conditions are negative for both sides. The floating ice and iceberg blocks battleships move which leads to this unexpected engagement highly dangerous, unpredictable and incontrollable.
But, fortunately, as an experienced navy commander, you are able to take opportunity to embattle the ships to maximize the utility of cannons on the battleships before the engagement.
The target is, arrange as many battleships as you can in the map. However, there are three rules so that you cannot do that arbitrary:
A battleship cannot lay on floating ice
A battleship cannot be placed on an iceberg
Two battleships cannot be arranged in the same row or column, unless one or more icebergs are in the middle of them.
Input
There is only one integer T (0<T<12) at the beginning line, which means following T test cases.
For each test case, two integers m and n (1 <= m, n <= 50) are at the first line, represents the number of rows and columns of the battlefield map respectively. Following m lines contains n characters iteratively, each character belongs to one of ‘#’, ‘*’, ‘o’, that symbolize iceberg, ordinary sea and floating ice.
Output
For each case, output just one line, contains a single integer which represents the maximal possible number of battleships can be arranged.
Sample Input
2
4 4
*ooo
o###
**#*
ooo*
4 4
#***
*#**
**#*
ooo#
Sample Output
3
5

题目大意:

    给出一个n行m列的图,*代表海域,o代表冰水,#代表冰山,要想在海域中放置船,保证船与船之间不能相互看到,之间只要有山就不能看到,问最多能放多少船。

解题思路:

    比赛的时候没有想出来,看了别人的博客也是花了很长时间才想明白为什么是二分匹配(在这里谢谢这些大牛,感谢你们的blog,要不我现在还不会呢。。。)。

    姑且将一片最多只能放一个船的连续网格叫做‘块’。

    以样例一为例

    首先只考虑行,将每个块标号:将答案存入num1

    1000

    0000

    2203

    0004

    再此只考虑列,将每个块标号:将答案存入num2

    1000

    0000

    1203

    0003

    那么对于任意一个可以放船的二维坐标A(i,j),假设其放船,那么num1与num2中与A(i,j)对应num相同的坐标都不能再放船。相当于A所在的行块和列块实现了一一映射关系。

    所以将行块看做一个集合,列块看做一个集合。

    所求的最大放船数就是两个集合之间的最大匹配数。

    匈牙利模版解决问题。

Code:

  1. /*************************************************************************
  2. > File Name: shanghai_1004.cpp
  3. > Author: Enumz
  4. > Mail: 369372123@qq.com
  5. > Created Time: 2014年11月04日 星期二 01时28分18秒
  6. ************************************************************************/
  7.  
  8. #include<iostream>
  9. #include<cstdio>
  10. #include<cstdlib>
  11. #include<string>
  12. #include<cstring>
  13. #include<list>
  14. #include<queue>
  15. #include<stack>
  16. #include<set>
  17. #include<algorithm>
  18. #include<cmath>
  19. #include<bitset>
  20. #include<climits>
  21. #define MAXN 100000
  22. using namespace std;
  23. bool edge[][];
  24. char map[][];
  25. int num1[][],num2[][],link[];
  26. bool vis[];
  27. int k1,k2,cnt;
  28. bool dfs(int x)
  29. {
  30. for (int y=; y<k2; y++)
  31. if (edge[x][y]&&!vis[y])
  32. {
  33. vis[y]=;
  34. if (link[y]==||dfs(link[y]))
  35. {
  36. link[y]=x;
  37. return true;
  38. }
  39. }
  40. return false;
  41. }
  42. void search()
  43. {
  44. //cout<<"1"<<endl;
  45. memset(link,,sizeof(link));
  46. for (int x=; x<k1; x++)
  47. {
  48. memset(vis,,sizeof(vis));
  49. if (dfs(x))
  50. cnt++;
  51. }
  52. }
  53. int main()
  54. {
  55. int T;
  56. cin>>T;
  57. while (T--)
  58. {
  59. int N,M;
  60. cin>>M>>N;
  61. //cout<<M<<N;
  62. memset(edge,,sizeof(edge));
  63. memset(num1,,sizeof(num1));
  64. memset(num2,,sizeof(num2));
  65. for (int i=; i<=M; i++)
  66. for (int j=; j<=N; j++)
  67. cin>>map[i][j];
  68. k1=k2=;
  69. for (int i=; i<=M; i++)
  70. {
  71. for (int j=; j<=N; j++)
  72. {
  73. if (map[i][j]=='#') k1++;
  74. if (map[i][j]=='*') num1[i][j]=k1;
  75. }
  76. k1++; //注意k累加的位置,放在for循环之后保证最后的块
  77. } //的编号为k-1
  78. for (int i=; i<=N; i++)
  79. {
  80. for (int j=; j<=M; j++)
  81. {
  82. if (map[j][i]=='#') k2++;
  83. if (map[j][i]=='*') num2[j][i]=k2;
  84. }
  85. k2++;
  86. }
  87. for (int i=; i<=M; i++)
  88. for (int j=; j<=N; j++)
  89. edge[num1[i][j]][num2[i][j]]=;
  90. cnt=;
  91. search();
  92. cout<<cnt<<endl;
  93. }
  94. return ;
  95. }

HDU5093——Battle ships(最大二分匹配)(2014上海邀请赛重现)的更多相关文章

  1. HDU5090——Game with Pearls(匈牙利算法|贪心)(2014上海邀请赛重现)

    Game with Pearls Problem DescriptionTom and Jerry are playing a game with tubes and pearls. The rule ...

  2. HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)

    Seam Carving DescriptionFish likes to take photo with his friends. Several days ago, he found that s ...

  3. HDU5099——Comparison of Android versions(简单题)(2014上海邀请赛重现)

    Comparison of Android versionsProblem DescriptionAs an Android developer, itˇs really not easy to fi ...

  4. Hdu5093 Battle ships 二分图

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission( ...

  5. Codeforces 567D:One-Dimensional Battle Ships(二分)

    time limit per test : 1 second memory limit per test : 256 megabytes input : standard input output : ...

  6. Battle ships HDU - 5093二分匹配

    Battle shipsHDU - 5093 题目大意:n*m的地图,*代表海洋,#代表冰山,o代表浮冰,海洋上可以放置船舰,但是每一行每一列只能有一个船舰(类似象棋的車),除非同行或者同列的船舰中间 ...

  7. HDOJ 5093 Battle ships 二分图匹配

    二分图匹配: 分别按行和列把图展开.hungary二分图匹配. ... 例子: 4 4 *ooo o### **#* ooo* 按行展开. .. . *ooo o#oo oo#o ooo# **#o ...

  8. Battle ships(二分图,建图,好题)

    Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  9. Codeforces 567D One-Dimensional Battle Ships

    传送门 D. One-Dimensional Battle Ships time limit per test 1 second memory limit per test 256 megabytes ...

随机推荐

  1. Excel中的宏--VBA的简单例子

    第一步:点击录制宏 第二步:填写宏的方法名 第三步:进行一系列的操作之后,关闭宏 第四步:根据自己的需要查看,修改宏 第六步:保存,一般是另存为,后缀名为.xlsm,否则宏语言不能保存. 到此为止恭喜 ...

  2. 自定义一个WPF的PathButton

    一.背景 做项目时总是少不了Button,但是普通的Button大家都不喜欢用,总是想要自定义的Button,正好项目中用到不要边框的Button,并且是形状也是根据功能不同而变化的,并且窗口程序是会 ...

  3. 1105. Spiral Matrix (25)

    This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasi ...

  4. C#二维数组及其本质(转)

    C#中二维数组包含两类:二维数组和数据矩阵.(这是我个人分类法,我认为比较能反映本质). 如上图,是二维数组,横向为第一维度,纵向为第二维度,不同维度可以有不同长度. 如果去掉元素7,那么上图也可能是 ...

  5. 多实例MySQL批量添加用户和密码并授权

    OS:Cent OS 6.3 DB:5.5.14 如果一台服务器上有100个MySQL数据库实例,此时需要给不同端口的几个数据库添加用户名.密码并授权应用IP,一个个授权没问题,反正累的不是我,哇咔咔 ...

  6. cocos2dx中的实现地图卷动的两种方式

    在游戏当中,实现地图卷动是最基本的功能,具体的实现的方法,大致有两类: 方法一:加载两张图片,轮流显示, 优点: 1.无论是地图上下卷动,还是左右卷动都可以 2.支持各种图片,(png,jpg...) ...

  7. Spiral Matrix II

    Spiral Matrix II Given an integer n, generate a square matrix filled with elements from 1 to n2 in s ...

  8. VBS基础篇 - Err对象

    Err对象是一个具有全局范围的内部对象,含有关于错误的所有信息.On Error Resume next 忽略运行时产生的所有错误On Error Goto 0 取消忽略错误措施主要方法有:Clear ...

  9. 机器学习(Machine Learning)&深度学习(Deep Learning)资料【转】

    转自:机器学习(Machine Learning)&深度学习(Deep Learning)资料 <Brief History of Machine Learning> 介绍:这是一 ...

  10. 【转发】SSH无密码登录的配置

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:http://cn.soulmachine.me/     原文地址:http ...