Fire Net

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

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
 

Source

 
X集合表示棋盘一行被墙分隔的点,Y表示棋盘一列被墙分隔的点,若(i,j)位置有棋子,则i在X集合中对应的点与j在Y集合中对应的点之间有一条连线,问题转换为二分图最大匹配。
 
 //2017-08-21
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
int head[N], tot;
struct Edge{
int to, next;
}edge[N<<]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++; edge[tot].to = u;
edge[tot].next = head[v];
head[v] = tot++;
} int n;
string G[N];
int matching[N];
int check[N]; bool dfs(int u){
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(!check[v]){//要求不在交替路
check[v] = ;//放入交替路
if(matching[v] == - || dfs(matching[v])){
//如果是未匹配点,说明交替路为增广路,则交换路径,并返回成功
matching[u] = v;
matching[v] = u;
return true;
}
}
}
return false;//不存在增广路
} //hungarian: 二分图最大匹配匈牙利算法
//input: null
//output: ans 最大匹配数
int hungarian(){
int ans = ;
memset(matching, -, sizeof(matching));
for(int u = ; u < n*n; u++){
if(matching[u] == -){
memset(check, , sizeof(check));
if(dfs(u))
ans++;
}
}
return ans;
} int main()
{
//freopen("inputA.txt", "r", stdin);
while(cin>>n && n){
init();
for(int i = ; i < n; i++)
cin>>G[i];
int id = , row_id[][], col_id[][];
memset(row_id, -, sizeof(row_id));
memset(col_id, -, sizeof(col_id));
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
if(G[i][j] == '.')row_id[i][j] = id;
else if(G[i][j] == 'X')id++;
}
id++;
}
id = n*n;
for(int j = ; j < n; j++){
for(int i = ; i < n; i++){
if(G[i][j] == '.')col_id[i][j] = id;
else if(G[i][j] == 'X')id++;
}
id++;
}
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
if(row_id[i][j] != - && col_id[i][j] != -)
add_edge(row_id[i][j], col_id[i][j]);
cout<<hungarian()<<endl;
} return ;
}

HDU1045(KB10-A 二分图最大匹配)的更多相关文章

  1. HDU1045 Fire Net —— 二分图最大匹配

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)  ...

  2. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  3. POJ2239 Selecting Courses(二分图最大匹配)

    题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...

  4. poj 2239 二分图最大匹配,基础题

    1.poj 2239   Selecting Courses   二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...

  5. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  6. 二分图最大匹配的K&#246;nig定理及其证明

     二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有.    以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上 ...

  7. POJ3057 Evacuation(二分图最大匹配)

    人作X部:把门按时间拆点,作Y部:如果某人能在某个时间到达某门则连边.就是个二分图最大匹配. 时间可以二分枚举,或者直接从1枚举时间然后加新边在原来的基础上进行增广. 谨记:时间是个不可忽视的维度. ...

  8. ZOJ1654 Place the Robots(二分图最大匹配)

    最大匹配也叫最大边独立集,就是无向图中能取出两两不相邻的边的最大集合. 二分图最大匹配可以用最大流来解. 如果题目没有墙,那就是一道经典的二分图最大匹配问题: 把地图上的行和列分别作为点的X部和Y部, ...

  9. HDU:过山车(二分图最大匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2063 题意:有m个男,n个女,和 k 条边,求有多少对男女可以搭配. 思路:裸的二分图最大匹配,匈牙利算法. 枚 ...

随机推荐

  1. VS 快捷键设置

    工具 --> 选项 --> 环境 --> 键盘

  2. 【ElasticSearch】:Windows下ElasticSearch+版本安装head

    概述 elasticsearch-head,之前插件plugin方式已废弃,现已改为nodejs的NPM安装,独立WEB服务方式. elasticsearch-head网址:https://githu ...

  3. HTTP的请求报文与响应报文

    报文: 简单来说,报文就是也就是HTTP报文,作用是在各个系统之间进行和响应时用来交换与传输的数据单元,即站点一次性要发送的数据块,这些数据块以一些文本形式的元信息开头,这些信息描述了报文的内容及含义 ...

  4. redis安装(linux)

    redis安装 1. 安装tcl # cd /usr/local # wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz # t ...

  5. 09-03 Java 抽象类

    抽象类的特点 /* 抽象类的概述: 动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的. 我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类. 抽象类的 ...

  6. odoo开发笔记--与微信集成

    odoo 与微信 https://github.com/JoneXiong/oejia_wx

  7. 解决 在 WINDOWS 下 同时安装 python2 python3 后 pip 错误

    再之前同时安装 python 后 只需把环境变量PATH 里面改为 PATH=C:\Python36-32\Scripts\;C:\Python36-32\;C:\Python27\;C:\Pytho ...

  8. (转)Python 日志处理(三) 日志状态码分析、浏览器分析

    原文:https://www.cnblogs.com/i-honey/p/7791564.html 在企业中,从日志中提取数据进行分析,可以帮助企业更加了解用户行为,用户最感兴趣的产品或者内容,分析得 ...

  9. android开发学习——day2

    简单了解了android stdio的操作方式,今天着手于探究活动(Activity) 了解了基本活动与手动创建活动的方法,了解了onCreate()方法,了解了创建和加载页面布局(layout) 新 ...

  10. Zookeeper--0300--java操作Zookeeper,临时节点实现分布式锁原理

    删除Zookeeper的java客户端有  : 1,Zookeeper官方提供的原生API, 2,zkClient,在原生api上进行扩展的开源java客户端 3, 一.Zookeeper原生API ...