HDU 5093 Battle ships(二分图最大匹配)
题意:一个m行n列的图由#、*、o三种符号组成,分别代表冰山、海域、浮冰,问最多可放的炮舰数(要求满足以下条件)
1、炮舰只可放在海域处
2、两个炮舰不能放在同一行或同一列(除非中间隔着一个或多个冰山)
分析:
1、如果单纯只考虑不能放在同一行同一列,那就是行号与列号的匹配,原理与UVALive 6811 Irrigation Line(二分图最小点覆盖--匈牙利算法)相同。
2、但现在隔着冰山可以放置炮舰,那假设某一行被冰山分隔成两部分,这一行的前半部分和后半部分可以看做是两行,再应用“行号”与“列号”的匹配的原理
3、既然要行号与列号匹配,那就要分别按照行和列给图标号
举例如下:

(1)若按行,则将海域从1开始标号,如果是连续的海域那标号相同,若有冰山分隔,标号加1.

PS:例如第三行22#3,此处2是形式意义上的第二行,因为有上述放置炮舰的原则,可以理解为是可以放置炮舰的第2行,而由于有冰山分隔,所以这一行的前后互不干扰,因此3可以理解为是可以放置炮舰的第3行
(2)按列同理

4、理论上讲海域可以放置炮舰,也就是说,有标号的地方可以放置炮舰,每一个放置的地方都是一个行号与列号的匹配,由此可得如下匹配

5、一条连线代表一个可放置的炮舰,求最大匹配即可
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) a < b ? a : b
#define Max(a, b) a < b ? b : a
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , -, };
const int dc[] = {-, , , };
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
char a[MAXN][MAXN];
int x[MAXN][MAXN];
int y[MAXN][MAXN];
int mp[MAXT][MAXT];
bool used[MAXT];
int match[MAXT];
int m, n, cnt1, cnt2;
void deal_row(){
cnt1 = ;
for(int i = ; i < m; ++i){
bool flag = false;
for(int j = ; j < n; ++j){
if(a[i][j] == '*'){
x[i][j] = cnt1;
flag = true;
}
if(a[i][j] == '#'){
++cnt1;
flag = false;
}
}
if(flag) ++cnt1;
}
}
void deal_column(){
cnt2 = ;
for(int i = ; i < n; ++i){
bool flag = false;
for(int j = ; j < m; ++j){
if(a[j][i] == '*'){
y[j][i] = cnt2;
flag = true;
}
if(a[j][i] == '#'){
++cnt2;
flag = false;
}
}
if(flag) ++cnt2;
}
}
bool Find(int x){
for(int i = ; i < cnt2; ++i){
if(mp[x][i] && !used[i]){
used[i] = true;
if(!match[i] || Find(match[i])){
match[i] = x;
return true;
}
}
}
return false;
}
void solve(){
int cnt = ;
for(int i = ; i < cnt1; ++i){
memset(used, false, sizeof used);
if(Find(i)) ++cnt;
}
printf("%d\n", cnt);
}
int main(){
int T;
scanf("%d", &T);
while(T--){
memset(a, , sizeof a);
memset(x, , sizeof x);
memset(y, , sizeof y);
memset(mp, , sizeof mp);
memset(match, , sizeof match);
scanf("%d%d", &m, &n);
for(int i = ; i < m; ++i)
scanf("%s", a[i]);
deal_row();
deal_column();
for(int i = ; i < m; ++i){
for(int j = ; j < n; ++j){
if(a[i][j] == '*'){
mp[x[i][j]][y[i][j]] = ;
}
}
}
solve();
}
return ;
}
HDU 5093 Battle ships(二分图最大匹配)的更多相关文章
- hdu 5093 Battle ships (二分图)
二分图最大匹配问题 遇到冰山就把行列拆成两个部分.每个部分x也好,y也好只能匹配一次 图画得比较草,将就着看 横着扫一遍,竖着扫一遍,得到编号 一个位置就对应一个(xi,yi)就是X集到Y集的一条边, ...
- HDOJ 5093 Battle ships 二分图匹配
二分图匹配: 分别按行和列把图展开.hungary二分图匹配. ... 例子: 4 4 *ooo o### **#* ooo* 按行展开. .. . *ooo o#oo oo#o ooo# **#o ...
- hdu 5093 Battle ships(二分图最大匹配)
题意: M*N的矩阵,每个格子上是三个之一:*.o.#. (1 <= m, n <= 50) *:海洋,战船可以停在上面. o:浮冰,战船 ...
- hdu 5093 Battle ships
二分图匹配 #include<cstdio> #include<cstring> #include<iostream> #include<cmath> ...
- hdu 5093 Battle ships 匈牙利 很巧妙的建图思路
//这题逼我把匈牙利学了 之前一直很勤快敲网络流 而且不以为耻反以为荣 解:首先按行扫描编号,如果在同一块中(即可以相互攻击),那么将其标为相同的数组,对列也做同样的操作. 然后扫描整张图,如果行编号 ...
- hdoj 5093 Battle ships 【二分图最大匹配】
题目:pid=5093" target="_blank">hdoj 5093 Battle ships 题意:给你一个n*m的图,图中有冰山 '# ',浮冰 'o' ...
- Battle ships(二分图,建图,好题)
Battle ships Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tot ...
- HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)
(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...
- hdu 1083 Courses(二分图最大匹配)
题意: P门课,N个学生. (1<=P<=100 1<=N<=300) 每门课有若干个学生可以成为这门课的代表(即候选人). 又规定每个学生最多只能成为一门课的代 ...
随机推荐
- vi 命令 使用方法
一.Unix编辑器概述 编辑器是使用计算机的重要工具之中的一个,在各种操作系统中,编辑器都是不可缺少的部件.Unix及其类似的ix 操作系统系列中,为方便各种用户在各个不同的环境中使用,提 ...
- HDOJ 1914 The Stable Marriage Problem
rt 稳定婚姻匹配问题 The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 6553 ...
- careercup-高等难度 18.5
18.5 有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离(也即相隔几个单词).有办法在O(1)时间里完成搜索操作吗?解法的空间复杂度如何? 解法1:我们假设单词wo ...
- 管理和维护RHCS集群
导读 管理和维护RHCS集群是一个非常复杂和繁琐的工作,要维护好一个RHCS集群,必须熟悉RHCS的基本运行原理,在集群管理方面,RHCS提供了两种方式:即Luci图形界面方式和命令行方式,这儿重点讲 ...
- PHP版根据经纬度和半径计算出经纬度的范围
百度地图提供了范围搜索的功能,但是它使用的是百度自己的数据,但是有时候我们需要使用自己的数据,显示在地图上.比如给定两个参数:指定位置(某一处的经纬度lnglat)和搜索半径(r),搜索指定范围内的数 ...
- MD5Encoder加密支持utf-8
import java.security.MessageDigest; public class MD5Encoder { public static String encode(String str ...
- (圆形imageview 类似qq头像)---》(ps:引用第三库APAvatarImageView>
使用方法:在故事版上把imageview的class名称设置为APAvatarImageView就可以显示圆形图,其他相关属性可以参考此类. demo下载地址 https://github.com/a ...
- 10 个顶级 JavaScript 动画框架推荐
使用JavaScript可以做出一些引人注目的动画效果,但通常不太容易实现.本文为你整理了10个非常优秀的JavaScript动画框架,使用它们你可以轻松实现动画效果.1. RaphaëlRaphaë ...
- Flume Spooldir 源的一些问题
Flume Spooldir 源的一些问题 来自:http://blog.xlvector.net/2014-01/flume-spooldir-source-problem/ ( 自己写的插件,数据 ...
- hust 1017 DLX
#include<set> #include<cmath> #include<queue> #include<cstdio> #include<v ...