Fire Net HDU - 1045(二分图匹配)-程序员宅基地

技术标签: 二分图匹配  

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<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e3+100;
char s[maxx][maxx];
int cntx[maxx][maxx];
int cnty[maxx][maxx];
int mzp[maxx][maxx];
int pre[maxx];
int vis[maxx];
int n;

inline void init()
{
    
	memset(cntx,0,sizeof(cntx));
	memset(cnty,0,sizeof(cnty));
	memset(mzp,0,sizeof(mzp));
	memset(pre,-1,sizeof(pre));
}
inline int dfs(int cur,int y)
{
    
	for(int i=1;i<=y;i++)
	{
    
		if(mzp[cur][i]&&!vis[i])
		{
    
			vis[i]=1;
			if(pre[i]==-1||dfs(pre[i],y))
			{
    
				pre[i]=cur;
				return 1;
			}
		}
	}
	return 0;
}
inline int match(int x,int y)
{
    
	int ans=0;
	for(int i=1;i<=x;i++)
	{
    
		memset(vis,0,sizeof(vis));
		ans+=dfs(i,y);
	}
	return ans;
}
int main()
{
    
	while(scanf("%d",&n),n)
	{
    
		init();
		for(int i=0;i<n;i++) scanf("%s",s[i]);
		int x=1;
		for(int i=0;i<n;i++)
		{
    
			for(int j=0;j<n;j++)
			{
    
				if(s[i][j]=='.') cntx[i][j]=x;
				else x++;
			}
			x++;
		}
		int y=1;
		for(int j=0;j<n;j++)
		{
    
			for(int i=0;i<n;i++)
			{
    
				if(s[i][j]=='.') cnty[i][j]=y;
				else y++;
			}
			y++;
		}
		for(int i=0;i<n;i++)
		{
    
			for(int j=0;j<n;j++)
			{
    
				if(s[i][j]=='.') mzp[cntx[i][j]][cnty[i][j]]=1;
			}
		}
		printf("%d\n",match(x,y));
	}
	return 0;
}

努力加油a啊,(o)/~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/starlet_kiss/article/details/101551169

智能推荐

ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)_动态第k大 树状数组套平衡树-程序员宅基地

文章浏览阅读294次。题目链接:题目大意:询问一个区间的第k大 但是有操作会对某个位置的值进行改变 即动态第k大思路:树状数组套主席树普通主席树装未修改的数据树状数组套主席树装的是修改的数据,即修改操作在树状数组中进行#include #include #include #include #include #include #include #include #include _动态第k大 树状数组套平衡树

oracle声明纪录变量,oracle – 在SQL * Plus中声明绑定变量-程序员宅基地

文章浏览阅读82次。不知道你为什么要使用PL / sql块.您没有使用您声明的ID,最好给它一个与列名称不同的名称以避免混淆.您可以在sql * Plus中声明一个绑定变量,然后选择:var l_test_quote varchar2(80); -- or whatever type/size you needvar l_test_id varchar2(80);declarel_id varchar2(80) :=..._"oracle:sp2-0552: 未声明绑定变量 \"empid\"。"

关于达梦数据库与oracle数据库的迁移_oracle迁移达梦方便吗-程序员宅基地

文章浏览阅读4.3k次,点赞2次,收藏9次。在这里和大家分享一下关于达梦与oracle之间进行数据迁移的注意事项:达梦数据库与oracle的兼容性是很高的,所以这两类数据库之间进行迁移 还是很方便的。首先,初始化实例的时候,将空格填充模式参数设置为零(BLANK_PAD_MODE=0),oracle兼容性参数 (COMPATIBLE_MODE=2)打开。需要注意的是,空格填充模式参数是初始化参数,只能在初始化实例的时候进行设置,这两个参..._oracle迁移达梦方便吗

优质的Unity调用Android交互方案_unity getactivity-程序员宅基地

文章浏览阅读214次。引言最近为了实现Unity与Android之间的通信,在网络上发现了很多种实现方案。有打包Jar的,有打包aar的,有直接拷贝文件的。试了几种方案虽然都能解决需求,但是使用起来给我的感觉并不是很舒服。在各种尝试中,已了解了Unity和Android之间通信的底层原理。该方案为本人结合Java特性所给出,可以减少很多其它方案的一些不明确以及繁琐的步骤。本文适用对象有一定的Unity开发经验,..._unity getactivity

javascript操作正则表达式对象的方法总结-程序员宅基地

文章浏览阅读41次。//正则表达式对象 /* var s = 'good good study day day up '; var r, re; re = new RegExp('study',"g"); //g表示全文搜索 i表示部分大小写 m多行搜索 r = s.match(re); alert(r); //st...

Java 缓冲流介绍_java缓冲流-程序员宅基地

文章浏览阅读906次。不用缓冲流的话,程序是读一个数据,写一个数据,大量占用了CPU,(本来CPU可以一次多处理内容的)处理这样在数据量大的程序中非常影响效率。缓冲流作用是把数据先写入缓冲区,等缓冲区满了,再把数据写到文件里。这样效率就大大提高了。缓冲输入流BufferedInputStream 缓冲输出流BufferedOutputStreamJavaimport java.io.BufferedInputStre_java缓冲流

随便推点

python 获取窗口句柄 模拟 点击按钮,python和pywin32实现窗口查找、遍历和点击-程序员宅基地

文章浏览阅读9.9k次,点赞5次,收藏45次。1.如何利用句柄操作windows窗体首先,获得窗体的句柄 win32api.FindWindows()第二,获得窗体中控件的id号,spy++第三,根据控件的ID获得控件的句柄(hwnd) GetDlgItem(hwnd,loginID)最后,利用控件句柄进行操作python可以通过win32api轻松获取控件的属性值通过标签找到主窗口句柄,然后通过主句柄获取下属控件句柄#-*- codin..._python 获取窗口句柄 模拟 点击按钮

以集群方式运行pyspark_spark.yarn.appmasterenv.pyspark_python-程序员宅基地

文章浏览阅读2.4k次。一、背景说明  单机执行pyspark(python on spark)非常简单,只要在脚本所在服务器上部署个python环境或Anaconda这种集成运行环境,再通过python3命令执行就完了。  而想将python提交到spark集群中运行,则有两种方法,一种是在每个spark结点上部署python环境,在spark低版本与python集成没那么完善的时候,集群结点数又不多的情况下,的确可以这么干(实际上我就这么干过),这种方式比较大的优势是每次执行pyspark任务时,不用分发python环_spark.yarn.appmasterenv.pyspark_python

Android修行手册 - 实现POI上万行的大数据量Excel读写操作,解决内存溢出_android 读取超大excel文件-程序员宅基地

文章浏览阅读1.5k次,点赞15次,收藏11次。搞过POI的都知道,在处理Excel文件时,POI提供了两种模式:用户模式和SAX事件驱动模式。用户模式API丰富使用起来相对简单,但当遇到大文件、大量数据或复杂格式时,可能会导致内存溢出。因此,官方推荐使用SAX事件驱动模式来解析大型Excel文件。开始想解决方法之前,我们要先知道 Excel2003与Excel2007 的区别。_android 读取超大excel文件

cordova通过原生实现自定义功能_cordova 连拍-程序员宅基地

文章浏览阅读1w次。先闲谈说下最近的微信要出的小程序吧,感觉确实很牛逼,革命说不上吧但是也是一个新的大的机遇。不得不承认腾讯有两个相当好的平台,一个是QQ,一个是微信,毕竟人数基数大,任何新的东西都会带来相当多的机会和挑战。那个小程序好像是基于react native,也是一种混合架构。最近整理整理下混合架构的知识,有时间也好好学习去。 好了开始正题吧。 最近研究cordova通过原生_cordova 连拍

DLL加载器-远程线程注入(常规dll注入)_dll注入器-程序员宅基地

文章浏览阅读909次。注入思路先获取到LoadLibrary的函数地址,之后使用CreateRemoteThread加载这段地址即可简单例子:D:\VS项目\Dll3\x64\Debug\Dll3.dllkernel.dll加载的地址在所有进程都是一样的https://zhuanlan.zhihu.com/p/599915628?utm_id=0DLL进程注入dll注入器生成dll-2-1.exe这里注入的exe是notepad++,找到其进程,注入的dll是我cs生成的beacon.dll主要思路是:_dll注入器

Oracle 11g DataGuard 搭建笔记(Windows Server 2016)_oracle创建一个新的dg-程序员宅基地

文章浏览阅读2.9k次,点赞4次,收藏16次。Oracle 11g DataGuard 搭建笔记(Windows Server 2016),Oracle 主从自动同步_oracle创建一个新的dg