HDU - 1045 Fire Net (缩点建图+二分图)

Fire Net

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


 

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

 

 

Recommend

 

              这道题的话,看完之后就知道是个匹配问题,但是却不清楚如何建图,进行连接和匹配。

              之后看了解析之后发现,可以将每一段横区间和列区间当作点,把可以相交的区间建立连接之后直接上匈牙利算法就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct ***
{
	int a = 0, b = 0;
};
*** id[6][6];
char map[6][6];
bool link[105][105];
bool vis[105];
int use[105];
int hcnt, rcnt ,n;
void dfsh(int x, int y) {
	if (y <= n && map[x][y] == '.') {
		id[x][y].a = hcnt;
		dfsh(x, y + 1);
	}
}void dfsr(int x, int y) {
	if (x <= n && map[x][y] == '.') {
		id[x][y].b = rcnt;
		dfsr(x+1, y );
	}
}
int found(int x)
{
	for (int s = 1; s < rcnt; s++) {
		if (link[x][s] && !vis[s]) {
			vis[s] = 1;
			if (use[s] == 0 || found(use[s])) {
				use[s] = x;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	memset(link, 0, sizeof(link));
	ios::sync_with_stdio(0);
	while (~scanf("%d", &n) && n)
	{
		memset(id, 0, sizeof(id));
		memset(link, 0, sizeof(link));
		memset(use, 0, sizeof(use));
		hcnt = rcnt = 1;
		for (int s = 1; s <= n; s++)
			for (int w = 1; w <= n; w++)
				cin >> map[s][w];
		for (int s = 1; s <= n; s++) 
			for (int w = 1; w <= n; w++) {
				if (map[s][w] == 'X') {
					continue;
				}
				if (id[s][w].a == 0) {
					dfsh(s, w);
					hcnt++;
				}
				if (id[s][w].b == 0) {
					dfsr(s, w);
					rcnt++;
				}
				link[id[s][w].a][id[s][w].b] = 1;
			}
		int sum = 0;
		for (int s = 1; s < hcnt; s++) {
			memset(vis, 0, sizeof(vis));
			if (found(s))sum++;
		}
	//	cout << hcnt << " " << rcnt << endl;
		printf("%d\n", sum);
	}
}

 

全部评论

相关推荐

shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务