hdu 1045 Fire Net(二分图)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1045
题目大意为给定一个最大为4*4的棋盘,棋盘可以放置堡垒,处在同一行或者同一列的堡垒可以相互攻击,在棋盘上也有城墙,可以隔离同一行同一列堡垒的相互攻击,“X”表示有城墙,“ . ”表示空地,问该棋盘最多可以放置多少个堡垒?
此题为二分图匹配问题,但是起初我不知道怎么建图,看题解发现一个规律,同一行同一列的连续空地不能放置两个堡垒,那么同一行同一列的连续空地的交点放置一个堡垒后,该行该列将不能再放置堡垒,这样很容易联想到二分图的性质,那么把连续“行”空地设为l集合,连续的“列”空地设为r集合,也就是说把连续行空地和连续列空地缩点,如果两者在原图中有交点,则可以建边,这样便可以轻易建图了,建图之后跑一下匈牙利算法即可得出答案,其二分图最大匹配数则为该棋盘最多可以放置的堡垒。
AC代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1001;
int visit[maxn];//访问数组
bool g[maxn][maxn];//建立二分图
int match[maxn];//匹配数组
int l,r;//l和r两集合
bool dfs(int u){
// i为建图后r集合的节点 ,u为l集合的节点
for(int i = 1;i<=r;i++){//依次遍历集合r
if(g[u][i] && !visit[i]){//如何u和i之间有边,而且i没有被访问过
visit[i] = true;//标记
if(match[i] == -1 || dfs(match[i])){//如果该i没有匹配过则直接匹配u,
//如果匹配过那么尝试dfs寻找增广路
match[i] = u;
return true;
}
}
}
return false;
}
int hungary(){
int ans = 0;
memset(match,-1,sizeof(match));//初始化r匹配的 l
for(int i = 1;i<=l;i++){
memset(visit,false,sizeof(visit));//初始化l的visit数组,表示都没有访问过
if(dfs(i)){//跑dfs遍历
ans++;//找到一个匹配
}
}
return ans;
}
int main(){
int n;
vector<int> res;
while(~scanf("%d",&n))
{
memset(g,false,sizeof(g));//初始化图
int markl[5][5];
vector<string> s;
if(n==0){
break;
}
for(int i = 0;i<n;i++){
string t;
cin>>t;
s.push_back(t); //存string数据
}
int step = 0;//step标记点的序号
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
//如下是缩点操作
if(s[i][j] == '.'){
if(j == 0){
step++;
markl[i][j] = step;
continue;
}
if(s[i][j-1] == 'X'){
step++;
}
markl[i][j] = step;
}
}
}
l = step;//记录集合l的数量
int markr[5][5];
step = 0;
for(int j = 0;j<n;j++){
for(int i = 0;i<n;i++){
if(s[i][j] == '.'){
if(i == 0){
step++;
markr[i][j] = step;
continue;
}
if(s[i-1][j] == 'X'){
step++;
}
markr[i][j] = step;
}
}
}
r = step;
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
if(s[i][j] == '.')
g[markl[i][j]][markr[i][j]] = true;//如果缩点后两者有交点,则在邻接矩阵上建边
}
}
cout<<hungary()<<endl;
}
return 0;
}
hdu 1045 Fire Net(二分图)的更多相关文章
- HDU 1045 Fire Net 二分图建图
HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...
- HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)
(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...
- hdu 1045 Fire Net 二分图匹配 && HDU-1281-棋盘游戏
题意:任意两个个'车'不能出现在同一行或同一列,当然如果他们中间有墙的话那就没有什么事,问最多能放多少个'车' 代码+注释: 1 //二分图最大匹配问题 2 //难点在建图方面,如果这个图里面一道墙也 ...
- HDOJ(HDU).1045 Fire Net (DFS)
HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...
- HDU 1045 Fire Net 【连通块的压缩 二分图匹配】
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1045(Fire Net)题解
以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...
- hdu 1045 Fire Net(最小覆盖点+构图(缩点))
http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS Memory Limit:32768KB ...
- HDU 1045 Fire Net(dfs,跟8皇后问题很相似)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】
Fire Net Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- HDU 1045 Fire Net 状压暴力
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
随机推荐
- StarUML 2下载、安装、破解全过程
StarUML官方下载地址: http://staruml.io/download 破解: 1.使用Editplus或者Notepad++等特殊的文本编辑器打开 安装位置下/www/lic ...
- Spring学习笔记-Spring之旅-01
使用Spring简化JAVA开发 Spring的四种关键策略: ●基于POJO的轻量级和最小侵入式编程: ●通过依赖注入(DI)和面向接口实现松耦合: ●基于切面(AOP)和惯例进行声明式编程. ●通 ...
- 虚拟机中的CentOS 7设置固定IP连接最理想的配置(转载)
来源:虚拟机中的CentOS 7设置固定IP连接最理想的配置(https://my.oschina.net/panhongju/blog/826814) 转载说明:这是我看了很多篇虚拟机静态IP配置写 ...
- centos8 ftp
安装 yum install -y vsftpd 启动 systemctl start vsftpd.service 开机启动 systemctl enable vsftpd.service 查看状态 ...
- 酷卓 一键ROOT教程
待编辑,还没写完 哈哈 酷卓 一键ROOT教程 首先简单介绍下酷卓. 酷卓由我个人开发,主要为了用户获取ROOT简单化,傻瓜化.酷卓获取方式:加QQ群 766969447 群文件下载就行 1. 手动选 ...
- window snmp
https://blog.csdn.net/weixin_30367543/article/details/99923014 https://jingyan.baidu.com/article/e3c ...
- window.resizeTo
概述 动态调整窗口的大小. 语法 window.resizeTo(aWidth, aHeight) 参数 aWidth 是一个整数,表示新的 outerWidth(单位:像素)(包括滚动条.窗口边框等 ...
- jquery tagsinput监听输入、修改、删除事件
个人博客 地址:http://www.wenhaofan.com/article/20181118192458 由于度娘上的根本搜不到对应的操作,连该插件对应的文档介绍都没有,不得已debug了源码才 ...
- eclipse怎么debug项目
1.打断点,服务器debug启动 2.debug:打断点,加项目.f5:进入方法 f6:下一行代码 f8:执行到下一个断点处
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) A Math Problem
//只要从所有区间右端点的最小值覆盖到所有区间左端点的最大值即可 #include<iostream> using namespace std ; int x,y; int n; int ...