Battle ships(二分图,建图,好题)

Battle ships

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1007    Accepted Submission(s): 353

Problem Description

Dear contestant, now you are an excellent navy commander, who is responsible of a tough mission currently.
Your fleet unfortunately encountered an enemy fleet near the South Pole where the geographical conditions are negative for both sides. The floating ice and iceberg blocks battleships move which leads to this unexpected engagement highly dangerous, unpredictable and incontrollable. 
But, fortunately, as an experienced navy commander, you are able to take opportunity to embattle the ships to maximize the utility of cannons on the battleships before the engagement. 
The target is, arrange as many battleships as you can in the map. However, there are three rules so that you cannot do that arbitrary:
A battleship cannot lay on floating ice A battleship cannot be placed on an iceberg
Two battleships cannot be arranged in the same row or column, unless one or more icebergs are in the middle of them.

Input

There is only one integer T (0<T<12) at the beginning line, which means following T test cases.
For each test case, two integers m and n (1 <= m, n <= 50) are at the first line, represents the number of rows and columns of the battlefield map respectively. Following m lines contains n characters iteratively, each character belongs to one of ‘#’, ‘*’, ‘o’, that symbolize iceberg, ordinary sea and floating ice.

Output

For each case, output just one line, contains a single integer which represents the maximal possible number of battleships can be arranged.

Sample Input

2
4 4
*ooo
o###
**#*
ooo*
4 4
#***
*#**
**#*
ooo#

Sample Output

3
5

题解:题意就是让找在这个矩阵中可以放的船最大数目;其中船之间可以有冰山,船间没冰山时船不能在同行同列;这样需要建图,先扫描行,如果遇到冰山t++;下一个数字可以继续匹配,下一行了t++,同样,再扫描列;得到二分匹配的x分部和y分部;

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
#define mem(x,y) memset(x,y,sizeof(x))
typedef long long LL;
#define SI(x) scanf("%d",&x)
#define SL(x) scanf("%lld",&x)
#define T_T while(T--)
#define F(i,x) for(i=0;i<x;i++)
#define PR(x) printf("%d",x)
#define PL(x) printf("%lld",x)
#define p_ printf(" ")
const int MAXN=1010;
char s[MAXN][MAXN];
int mp[MAXN][MAXN],vis[MAXN],link[MAXN],x[110][110],y[110][110];
int m,n,t1,t2;
int getmpxy(int rl,int a[][110]){//扫描行和列得到二分匹配的x部和y部
	int t=0,i,j;
	if(rl)F(i,m){
		F(j,n){
			if(s[i][j]==‘*‘)a[i][j]=t;
			if(s[i][j]==‘#‘)t++;
		}
		t++;
	}
	else F(j,n){
		F(i,m){
			if(s[i][j]==‘*‘)a[i][j]=t;
			if(s[i][j]==‘#‘)t++;
		}
		t++;
	}
	return t;
}
void getmp(){
	mem(x,0);mem(y,0);
	t1=getmpxy(1,x);
	t2=getmpxy(0,y);
	int i,j;
	F(i,m){
		F(j,n){
			if(s[i][j]==‘*‘){
			//	printf("%d %d\n",x[i][j],y[i][j]);
				mp[x[i][j]][y[i][j]]=1;
			}
		}
	}
}
bool dfs(int x){
	int i,j;
	F(i,t2){
		if(!vis[i]&&mp[x][i]){
			vis[i]=1;
			if(link[i]==-1||dfs(link[i])){//||
				link[i]=x;
				return true;
			}
		}
	}
	return false;
}
int km(){
	mem(link,-1);
	int i,j;
	int ans=0;
	F(i,t1){
		mem(vis,0);
		if(dfs(i))ans++;
	}
	return ans;
}
int main(){
	int T;
	SI(T);
	T_T{
		SI(m);SI(n);
		int i,j;
		mem(mp,0);
		F(i,m)
		scanf("%s",s[i]);
		getmp();
		PR(km());
		puts("");
	}
	return 0;
}

  

时间: 2024-12-27 08:09:30

Battle ships(二分图,建图,好题)的相关文章

POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)

题目链接:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 3325 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobi

HDOJ 5093 Battle ships 二分图匹配

二分图匹配: 分别按行和列把图展开,hungary二分图匹配.... 样例: 4 4 *ooo o### **#* ooo* 按行展开.... *ooo o#oo oo#o ooo# **#o ooo* ooo* 再按列展开... 7 * 8 *ooooooo oooooooo oooooooo oooooooo *o*ooooo ooooooo* ooooooo* 匹配结果3 Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memo

POJ 2195 一人一房 最小费用流 建图 水题

Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 21010   Accepted: 10614 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertica

hdu 5093 Battle ships 二分图匹配

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5093 一开始就往贪心的方向想了结果wa全场 这种矩阵形式的图一般要联想到行和列构成了二分图 然后实质就是求一个最大匹配 中间的冰山实际上就是把一行或一列切成多个顶点而已 所以一开始预处理一下 然后就可以套用模板 #include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #i

hdu 5093 Battle ships二分图

二分图最大匹配问题 遇到冰山就把行列拆成两个部分.每个部分x也好,y也好只能匹配一次 图画得比较草,将就着看 横着扫一遍,竖着扫一遍,得到编号 一个位置就对应一个(xi,yi)就是X集到Y集的一条边, 由题意,每个点只能被选择一次.所以最大匹配的边数就是答案了. 算法过程 通常都是先贪心求一个匹配,然后开始增广. 寻找增广路的过程: 一个没有和任意边匹配的点叫做未盖点,从左集X中一个未盖点u出发寻找增广路. 从u出发,选一个非匹配边到达Y集中的v,如果v没匹配,那么就找到一条增广路(只要把之前走

HDU5093 Battle ships (二分图)

题意:给你一个m*n(1<=m,n<=50)的图,其中 '#'代表冰山, '*'代表海洋, 'o'代表浮冰..然后让你尽可能放置最多的船,但是要满足一下规矩: 船不能放在冰山上: 船不能放到浮冰上 两艘船之间除非中间有冰山,否则不能在同一列或同一行. 分析:红果果的二分最大匹配....图也很容易构造...把每一行被冰山分隔开来的海洋格子连通块(至少一个格子)作为X点,同样的每一列被冰山分隔开来的海洋格子连通块作为Y点,X点与Y点有边相连当且仅当这两个连通块共用一个海洋格子.然后跑二分最大匹配.

Poj_2536 Gopher II -二分图建图

题目:有m个洞,n知动物,每个洞容一知动物,问当天敌来后最少有多少知动物不能逃亡. 没看清楚最后的输出,被坑了几发 /************************************************ Author :DarkTong Created Time :2016/7/31 16:12:15 File Name :Pos_2536.cpp *************************************************/ //#include <bits/

POJ 3281 Dining (网络流最大流 拆点建图 Edmonds-Karp算法)

Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10159   Accepted: 4676 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others. Farmer John has cooked fabulo

POJ-3020 Antenna Placement---二分图匹配&amp;最小路径覆盖&amp;建图

题目链接: https://vjudge.net/problem/POJ-3020 题目大意: 一个n*m的方阵 一个雷达可覆盖两个*,一个*可与四周的一个*被覆盖,一个*可被多个雷达覆盖问至少需要多少雷达能把所有的*覆盖 解题思路: 把每个*城市编号,然后每相邻两个城市之间连线.这里求最少多少个雷达可以覆盖完*,就是二分图匹配中的最小路径覆盖数,但是这里的图的边是双向的.举个例子 o*o **o ooo 这里可以编号成 010 230 000 那么有边<1,3><3,1><