hdu 1045 && zoj 1002 Fire Net(DFS && 二分图匹配)

Fire Net

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 7958    Accepted Submission(s): 4542

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

Zhejiang University Local Contest 2001

DFS深度优先还得多练习啊,下边还有单靠大神的代码用二分图写的代码,第一次用,,只怪自己太菜

//DFS
#include<stdio.h>
#include<string.h>
char mp[8][8];
int n,ans;
int check(int x,int y){
	int i;
	//判断行是否冲突
	for(i=y-1;i>0;i--){
		if(mp[x][i]=='#') return 0;
		if(mp[x][i]=='X') break;
	}
	for(i=y+1;i<=n;i++){
		if(mp[x][i]=='#') return 0;
		if(mp[x][i]=='X') break;
	}
	//判断列是否冲突
	for(i=x-1;i>0;i--){
		if(mp[i][y]=='#') return 0;
		if(mp[i][y]=='X') break;
	}
	for(i=x+1;i<=n;i++){
		if(mp[i][y]=='#') return 0;
		if(mp[i][y]=='X') break;
	}
	return 1;
}

void dfs(int cnt){
	if(cnt>ans) ans=cnt;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			if(mp[i][j]=='.'&&check(i,j)){
				mp[i][j]='#';
				dfs(cnt+1);
				mp[i][j]='.';
			}
		}
}
int main(){
	int i,j;
	while(scanf("%d",&n),n){
		for(i=1;i<=n;i++){
			getchar();
			for(j=1;j<=n;j++){
				scanf("%c",&mp[i][j]);
			}
		}
		ans=0;
		dfs(0);
		printf("%d\n",ans);
	}
	return 0;
}
//下边是用二分图匹配写的代码
#include<stdio.h>
#include<string.h>
char mp[8][8];
int r[8][8],c[8][8],path[8][8];
int n,rmax,cmax,ruse[8],cuse[8],vis[8];
int Find(int x){
	for(int i=1;i<cmax;i++){//在列集合中找到有路径的点
		if(!vis[i] && path[x][i]){
			vis[i]=1;
			if(!cuse[i] || Find(cuse[i])){
				cuse[i]=x;//分别赋值
				ruse[x]=i;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	int i,j;
	while(scanf("%d",&n),n){
		for(i=1;i<=n;i++){
			getchar();
			for(j=1;j<=n;j++){
				scanf("%c",&mp[i][j]);
			}
		}
		memset(r,-1,sizeof(r));
		memset(c,-1,sizeof(c));
		//缩点
		rmax=cmax=1;
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				if(mp[i][j]=='.'&&r[i][j]==-1){//横向缩点
					for(int k=j;k<=n&&mp[i][k]=='.';k++)
						r[i][k]=rmax;//相同区域标记同一个数字
					rmax++;
				}
				if(mp[j][i]=='.'&&c[j][i]==-1){//纵向缩点
					for(int k=j;k<=n&&mp[k][i]=='.';k++)
						c[k][i]=cmax;//相同区域标记同一个数字
					cmax++;
				}
			}
		}
		//连边建立路径图
		memset(path,0,sizeof(path));
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++){
				if(mp[i][j]=='.'){
					path[ r[i][j] ][ c[i][j] ]=1;
				}
			}
		//二分图匹配
		int ans=0;
		memset(ruse,0,sizeof(ruse));
		memset(cuse,0,sizeof(cuse));
		for(i=1;i<rmax;i++) {// 行集合中搜索
			memset(vis,0,sizeof(vis));
			ans+=Find(i);
		}

		printf("%d\n",ans);
	}
	return 0;
}
时间: 2024-11-09 10:12:45

hdu 1045 && zoj 1002 Fire Net(DFS && 二分图匹配)的相关文章

ZOJ 1002 Fire Net

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 thro

HDU 1507 Uncle Tom&#39;s Inherited Land*(二分图匹配)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3339    Accepted Submission(s): 1394Special Judge Problem Description Your old uncle Tom inherited a piece of land fro

HDU 3081:Marriage Match II(二分图匹配+并查集)

http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意:有n个男生n个女生,他们只有没有争吵或者女生a与男生A没有争吵,且女生b与女生a是朋友,因此女生b也可以和男生A过家家(具有传递性).给出m个关系,代表女生a和男生b没有争吵过.给出k个关系,代表女生a与女生b是好朋友.每一轮过家家之后,女生只能选择可以选择并且没选过的男生过家家,问游戏能进行几轮. 思路:因为n<=100,因此支持O(n^3)的算法,挺容易想到是一个二分图匹配的.(出现在我的网络

HDU 5727 Necklace ( 2016多校、二分图匹配 )

题目链接 题意 : 给出 2*N 颗珠子.有 N 颗是阴的.有 N 颗是阳的.现在要把阴阳珠子串成一个环状的项链.而且要求珠子的放置方式必须的阴阳相间的.然后给出你 M 个限制关系.格式为 ( A.B ) 表示如果阳性 A 珠子和阴性 B 珠子相邻的话.那么阳性珠子就会衰弱.问你在最优的情况下.最少有多少颗阳珠子是衰弱的 分析 : 看题目 N 的大小只有 9 不免让人浮想联翩.跃跃欲试枚举暴力 直接暴力还是不行的 首先先枚举阴珠子所在的位置 这个可以用 next_permutation 解决 然

ZOJ 1002 Fire Net(dfs)

嗯... 题目链接:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364501 这道题是想出来则是一道很简单的dfs: 将一个4*4的地图给每一个点排序,如下图: 0  1  2  3 4  5  6  7 8  9  10  11 12 13 14 15 设一个点为第k个点,那么它的坐标为(k/n,k%n),根据这个进行dfs,当k == n * n是退出dfs.如果k < n *n,就继续dfs,判断是否能放下,即要

ZOJ 1002 Fire Net(DFS啊 )

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2 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

POJ 1071 &amp; HDU 1364 &amp; ZOJ 1019 Illusive Chase(DFS)

题目链接: POJ:http://poj.org/problem?id=1071 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1364 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=19 Description Tom the robocat is presented in a Robotics Exhibition for an enthusiastic audien

[ZOJ 1002] Fire Net (简单地图搜索)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1002 题目大意: 给你一个n*n的地图,地图上的空白部分可以放棋子,也有墙,问最多能放多少棋子使得棋子两两不会袭击? 棋子袭击当且仅当处在同一行或者同一列上并且中间没有墙的阻隔. 真是好久没写过搜索题了..这道题都写了这么久!! 直接写dfs(x,y,now) 代表我现在站在x点,y点上,那么就只能产生两种状态,放棋子或者不放棋子. 然后写一个C(x,y)代表当

HDU 2389 Rain on your Parade (二分图匹配(Hopcroft-Carp的算法模板))

Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Others) Total Submission(s): 3033    Accepted Submission(s): 952 Problem Description You're giving a party in the garden of your villa by the sea. The p