4554: [Tjoi2016&Heoi2016]游戏

Description

在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看
是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张
地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一
列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张n*m的网格地图:其中*代表空地,炸弹的威力可
以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸
弹的威力是不能穿透的,不能在此放置炸弹。例如:给出1*4的网格地图*xx*,这个地图上最多只能放置一个炸弹
。给出另一个1*4的网格地图*x#*,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最
多能放置多少炸弹

Input

第一行输入两个正整数n,m,n表示地图的行数,m表示地图的列数。1≤n,m≤50。接下来输入n行m列个字符,代表网
格地图。*的个数不超过n*m个

Output

输出一个整数a,表示最多能放置炸弹的个数

Sample Input

4 4
#∗∗∗
∗#∗∗
∗∗#∗
xxx#

Sample Output

5
 
最近在学二分图匹配,随便找了一道发现完全没有思路……没有看出来是二分图匹配……
思维不够活跃还没有形成套路啊
正式讲一下做法……
每个点看成一条边,拆点,将每个点分别拆成以行,列为标准的两点,遇到#视为换行/列,
再缩点,在一个连通块的点缩为一点。
令以行为标准的点为左边的点,以列为标准的点为右边的点。
(因为对于地图上的点,一个连通块中只能有一个点放炸弹,以此连接行列,
对应二分图中一个点只能有一个匹配,所以可以把这个看做二分图。)
接着匹配即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define Max 205
int n,m,num1=1,num2=1,dis=Max,res=0;
char s[100][100];
int x[3000][1300],y[3000][3000],mp[3000][3000],dx[10000],dy[10000],cx[10000],cy[10000],vis[10000],pdx[10000],pdy[10000];
int bfs()
{
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
dis=Max;
queue<int> q;
for (int i=1;i<=num1;i++)
{
if (!cx[i]&&pdx[i])
q.push(i);
}
while (!q.empty())
{
int u=q.front();
q.pop();
if (dx[u]>dis) break;
for (int i=1;i<=num2;i++)
{
if (mp[u][i]&&!dy[i]&&pdy[i])
{
dy[i]=dx[u]+1;
if (!cy[i]) dis=dy[i];
else
{
dx[cy[i]]=dy[i]+1;
q.push(cy[i]);
}
}
}
}
return dis!=Max;
}
int find(int u)
{
for (int i=1;i<=num2;i++)
{
if (!vis[i]&&mp[u][i]&&dy[i]==dx[u]+1&&pdy[i])
{
vis[i]=1;
if (cy[i]&&dy[i]==dis) continue;
if (!cy[i]||find(cy[i]))
{
cx[u]=i;cy[i]=u;
return 1;
}
}
}
return 0;
} int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%s",s[i]+1);//输入
for (int i=1;i<=n;i++)//以行为标准
{
for (int j=1;j<=m;j++)
{
if (s[i][j]=='#') num1++;//每个num1相同的点即可缩为一个点
x[i][j]=num1;
pdx[num1]=1;
}
num1++;
}
for (int j=1;j<=m;j++)//以列为标准
{
for (int i=1;i<=n;i++)
{
if (s[i][j]=='#') num2++;//同上
y[i][j]=num2;
pdy[num2]=1;
}
num2++;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if(s[i][j]=='*')//连边
{
mp[x[i][j]][y[i][j]]=1;
//mp[y[i][j]][x[i][j]]=1;
}
}
while (bfs())//二分图匹配,这里用的hopcroft-karp算法,主要想练一下……
{
memset(vis,0,sizeof(vis));
for (int i=1;i<=num1;i++)
{
if (!cx[i]&&pdx[i])
res+=find(i);
}
} cout<<res;
return 0;
}

bzoj4554: [Tjoi2016&Heoi2016]游戏 二分图匹配的更多相关文章

  1. BZOJ 4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

    4554: [Tjoi2016&Heoi2016]游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4554 Descripti ...

  2. 4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4554 题解: 如果没有硬石头的话,就是’*‘点对应的行列建边,然后跑最大匹配 硬石头什么 ...

  3. bzoj4554: [Tjoi2016&Heoi2016]游戏(二分图匹配)

    4554: [Tjoi2016&Heoi2016]游戏 题目:传送门 题解: 一道很牛逼的匈牙利..和之前模拟赛的一道题有点相似(不过这题不用完美匹配) 我们可以把连续的行和列全部编号(如果之 ...

  4. 【BZOJ4554】[Tjoi2016&Heoi2016]游戏 二分图最大匹配

    [BZOJ4554][Tjoi2016&Heoi2016]游戏 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 ...

  5. BZOJ4554 - [TJOI2016&HEOI2016]游戏

    原题链接 Description 给出一个的地图,地图上有空地.软石头和硬石头.求在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到.炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威 ...

  6. [BZOJ4554][TJOI2016&&HEOI2016]游戏(匈牙利)

    4554: [Tjoi2016&Heoi2016]游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 857  Solved: 506[Sub ...

  7. BZOJ4554: [Tjoi2016&Heoi2016]游戏

    Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了这样一 ...

  8. BZOJ 4554 [Tjoi2016&Heoi2016]游戏 ——二分图

    出原题,直接二分图匹配即可. #include <cstdio> #include <vector> #include <cstring> using namesp ...

  9. BZOJ4554: [Tjoi2016&Heoi2016]游戏 luoguP2825 loj2057

    题面描述:尽可能多的放置符合要求的炸弹. 分析: 在i,j处放置炸弹,则在第i行,上一个硬石头之后,下一个硬石头之前,第j列,上一个硬石头之后,下一个硬石头之前,不能再次放置炸弹. 首先,这个题,一看 ...

随机推荐

  1. [bzoj1195] [hnoi2006] 最短母串

    本题是一个经典的状压dp问题,在紫书中有着加强版的例题. 本题的难度主要体现在:如何输出字符串字典序最小. 为了解决这个问题,我们有两种常用方案: 1) 我们可以采用bfs输出路径的方法,使用+1来输 ...

  2. UIAlertController 自定义输入框及KVO监听 分类: ios技术 2015-01-20 15:33 199人阅读 评论(1) 收藏

    UIAlertController极大的灵活性意味着您不必拘泥于内置样式.以前我们只能在默认视图.文本框视图.密码框视图.登录和密码输入框视图中选择,现在我们可以向对话框中添加任意数目的UITextF ...

  3. 浅谈一个网页打开的全过程(涉及DNS、CDN、Nginx负载均衡等)

    1.概要 从用户在浏览器输入域名开始,到web页面加载完毕,这是一个说复杂不复杂,说简单不简单的过程,下文暂且把这个过程称作网页加载过程.下面我将依靠自己的经验,总结一下整个过程.如有错漏,欢迎指正. ...

  4. Java的内存泄漏

    内存泄漏是指,无用对象(不再使用的对象)持续占用内存或者无用对象的内存得不到及时释放,从而造成的内存浪费 就说是有一块内存你不需要再用了,但是呢你还保留着它的指针,那么这块内存就不会被回收 举个例子 ...

  5. DownloadManager 版本更新,出现 No Activity found to handle Intent 的解决办法

    项目中,进行版本更新的时候,用的是自己写的下载方案,最近看到了使用系统服务 DownloadManager 进行版本更新,自己也试试. 在下载完成以后,安装更新的时候,出现了一个 crash,抓取的 ...

  6. sqlserver 批量删除相同前缀名的表

    ) DECLARE tmpCur CURSOR FOR SELECT name FROM sys.objects WHERE TYPE='U' AND name LIKE N'HSUPA%' OPEN ...

  7. IOS开发中Xcode常用插件安装与管理(转)

    XCode中插件管理工具:Alcatraz    转自http://www.cocoachina.com/industry/20140506/8325.html 苹果现在的成绩得益于其始终如一的坚持. ...

  8. java8 泛型声明 The diamond operator ("<>") should be used

    The diamond operator ("<>") should be used Java 7 introduced the diamond operator (& ...

  9. pandas 按照列A分组,将同一组的列B求和,生成新的Dataframe

    对于pandas中的Dataframe,如果需要按照列A进行分组,将同一组的列B求和,可以通过下述操作完成: df = df.groupby(by=['column_A'])['column_B']. ...

  10. JAVA WEB 中的编码分析

    JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...