Fire Net

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9897    Accepted Submission(s): 5750

Problem Description
Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least
one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses
in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration. 

 
Input
The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The
next n lines each describe one row of the map, with a '.' indicating an open space and an uppercase 'X' indicating a wall. There are no spaces in the input file. 
 
Output
For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.
 
Sample Input
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
 
Sample Output
5
1
5
2
4
 

这题用普通DFS+回溯比较好想得到,但是用二分就比较麻烦……看了下大牛的思路,是把每一个给每一个行连通分量和列连通分量标号,然后再对每一个点行列加边,可以发现每一个'.'都是一个行与列连通分量的交叉点即两者的匹配,匹配之后这个行与列连通分量中不能再出现任何的炮台,符合了匹配的思想即,然后进行建图……主要就是建图方法比较难想到……感叹想到这个建图方法的人好机智啊……

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x,y) memset(x,y,sizeof(x))
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=100;
struct info
{
int to;
int pre;
}E[N];
int head[N],cnt,vis[N],match[N];
char pos[N][N];
pii num[N][N];
void add(int s,int t)
{
E[cnt].to=t;
E[cnt].pre=head[s];
head[s]=cnt++;
}
void init()
{
MM(head,-1);
cnt=0;
MM(match,-1);
MM(pos,-1);
MM(num,0);
}
int dfs(int now)
{
for (int i=head[now]; ~i; i=E[i].pre)
{
int v=E[i].to;
if(!vis[v])
{
vis[v]=1;
if(match[v]==-1||dfs(match[v]))
{
match[v]=now;
match[now]=v;
return 1;
}
}
}
return 0;
}
int main(void)
{
int n,i,j,k,ur,ul;
while (~scanf("%d",&n)&&n)
{
init();
char c;
for (i=0; i<n; i++)
scanf("%s",pos[i]);
ur=ul=0;
for (i=0; i<n; i++)
{
int flag=1;
for (j=0; j<n; j++)
{
if(pos[i][j]!='X')
{
if(flag)
{
num[i][j].first=++ur;
flag=0;
}
else
num[i][j].first=num[i][j-1].first;
}
else
flag=1;
}
}
for (j=0; j<n; j++)
{
int flag=1;
for (i=0; i<n; i++)
{
if(pos[i][j]!='X')
{
if(flag)
{
num[i][j].second=++ul;
flag=0;
}
else
num[i][j].second=num[i-1][j].second;
}
else
flag=1;
}
}
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
if(num[i][j].first&&num[i][j].second)
add(num[i][j].first,ur+ul+num[i][j].second);
}
}
int r=0;
for (i=1; i<=ur; i++)
{
MM(vis,0);
if(dfs(i))
r++;
}
printf("%d\n",r);
}
return 0;
}

HDU——1045Fire Net(最大匹配)的更多相关文章

  1. HDU 2853 (KM最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题目大意:二分图匹配费用流.①最大匹配②最小原配变动 解题思路: 如果去掉第二个要求,那么就是裸 ...

  2. hdu 1281 二分图最大匹配

    对N个可以放棋子的点(X1,Y1),(x2,Y2)......(Xn,Yn);我们把它竖着排看看~(当然X1可以对多个点~) X1   Y1 X2   Y2 X3   Y3 ..... Xn   Yn ...

  3. hdu 4619 二分图最大匹配 ——最大独立集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4619 #include <cstdio> #include <cmath> # ...

  4. B - The Accomodation of Students - hdu 2444(最大匹配)

    题意:现在有一些学生给你一下朋友关系(不遵守朋友的朋友也是朋友),先确认能不能把这些人分成两组(组内的人要相互不认识),不能分的话输出No(小写的‘o’ - -,写成了大写的WA一次),能分的话,在求 ...

  5. HDU 3279 二分图最大匹配

    DES: 就是说对每个人都给你一个区间.但一个人只匹配一个数.问你满足匹配的人的序号字典序最大时的最大匹配是什么. 前几天刚做的UVALive 6322...当然是不一样的...那个要求的最大匹配的个 ...

  6. HDU - 2444 二分图最大匹配 之 判断二分图+匈牙利算法

    题意:第一行给出数字n个学生,m条关系,关系表示a与b认识,判断给定数据是否可以构成二分图,如果可以,要两个互相认识的人住一个房间,问最大匹配数(也就是房间需要的最小数量) 思路:要看是否可以构成二分 ...

  7. hdu 3729(二分图最大匹配)

    I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. hdu 4185 二分图最大匹配

    Oil Skimming Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  9. hdu 1083 Courses (最大匹配)

    CoursesTime Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. Android - Zxing实现二维码的扫描与生成

    Zxing: Zxing是一个开放源码,用java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口.可以实现使用手机内置摄像头完成条形码的扫描以及解码. github:     ...

  2. 【extjs6学习笔记】0.0 准备

    1.下载ExtJS 6 下面是Ext JS 6正式版的GPL版本下载地址 https://www.sencha.com/legal/gpl/ 2.下载sencha cmd 安装完成后,命令行运行出现以 ...

  3. 修改nagios登录界面密码

    htpasswd -c /usr/local/nagios/etc/htpasswd.user nagiosadmin 输入密码: 重启httpd服务.

  4. Javafinal方法

    class Animal{     public final void eat(){         System.out.println("吃");     } } class ...

  5. codevs 2038 香甜的黄油 USACO

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖放在一片牧场上 ...

  6. (十四)maven之启动tomcat

    前言:在网上找了好几种方法启动web项目.比较好用的是:①在Project Facets勾上Dynamic....,但是这个方法会改变项目结构(把WebContent的东西都弄出来了):②使用jett ...

  7. ubuntu 16.0安装 hadoop2.8.3

    环境:ubuntu 16.0 需要软件:jdk ssh https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ 2.8.3 安装 jdk并 ...

  8. Maven归纳

      一.常用功能 1.Maven的中央仓库 https://mvnrepository.com/ 2.添加jar包依赖 1.首先点击pom.xml,然后点击弹出页面中的Dependencies选项,接 ...

  9. 多线程threadvar 变量设定

    Delphi管理多线程之线程局部存储:threadvar 尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题.其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一 ...

  10. kubernetes概念

    kubernetes blog cluster cluster是计算.存储.和网络资源的集合,kubernetes利用这些资源运行各种基于容器的应用. master master是cluster的大脑 ...