博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU5093——Battle ships(最大二分匹配)(2014上海邀请赛重现)
阅读量:5133 次
发布时间:2019-06-13

本文共 3451 字,大约阅读时间需要 11 分钟。

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
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #define MAXN 10000022 using namespace std;23 bool edge[3000][3000];24 char map[100][100];25 int num1[100][100],num2[100][100],link[3000];26 bool vis[3000];27 int k1,k2,cnt;28 bool dfs(int x)29 {30 for (int y=1; y
>T;57 while (T--)58 {59 int N,M;60 cin>>M>>N;61 //cout<
<
>map[i][j];68 k1=k2=1;69 for (int i=1; i<=M; i++)70 {71 for (int j=1; 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-178 for (int i=1; i<=N; i++)79 {80 for (int j=1; 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=1; i<=M; i++)88 for (int j=1; j<=N; j++)89 edge[num1[i][j]][num2[i][j]]=1;90 cnt=0;91 search();92 cout<
<

 

转载于:https://www.cnblogs.com/Enumz/p/4072647.html

你可能感兴趣的文章
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>
Flask 系列之 SQLAlchemy
查看>>
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
[HDU3683 Gomoku]
查看>>
下一代操作系统与软件
查看>>
[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
查看>>
Python IO模型
查看>>
DataGridView的行的字体颜色变化
查看>>
局域网内手机访问电脑网站注意几点
查看>>
[Serializable]的应用--注册码的生成,加密和验证
查看>>
Android-多线程AsyncTask
查看>>
LeetCode【709. 转换成小写字母】
查看>>
CF992E Nastya and King-Shamans(线段树二分+思维)
查看>>