标签:des style blog http io color ar os java
2 4 4 *ooo o### **#* ooo* 4 4 #*** *#** **#* ooo#
3 5
题意 : 给你一张 n*m 的矩阵图形 ,‘ * ’ 表示 空地 , ‘ o ’ 表示浮冰 , ‘ # ’ 表示 冰山 , 你
可以在空地上方战舰 , 但是同一行或同一列只能放一个战舰。若两个战舰想放在同一行或同一
列上,那么它们之间必须要有冰山相隔。然后问你在这张图上最多可以放多少个战舰 ?
思路 : 二部图的最大匹配问题 ,将行和列方别当成一个集合 ,每一行和每一列方别当成对应
集合的点。若行或列中有 ’ # ‘ ,就把行或列拆点。 就以样例 一为例:
*ooo 行集合(将 ’ * ‘标号) 1ooo 列集合 1ooo
o### o### o###
**#* 22#3 23#4
ooo* ooo4 ooo4
然后看原图 ’ * ‘ 的位置,就可以建图了 。
然后求出图的最大匹配就是答案了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 55*30;
const int maxn = 55;
int a[maxn][maxn],b[maxn][maxn],match[N],n,m,p,q;
bool con[N][N],vis[N];
char ch[maxn][maxn];
void initial()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(con,0,sizeof(con));
memset(match,-1,sizeof(match));
}
void input()
{
scanf("%d %d",&n,&m);
for(int i=0; i<n; i++) scanf("%s",ch[i]);
}
void creat_row()
{
p=1;
bool flag;
for(int i=0; i<n; i++)
{
flag=0;
for(int j=0; j<m; j++)
{
if(ch[i][j]=='*')
{
a[i][j]=p;
flag=1;
}
if(ch[i][j]=='#')
{
p++;
flag=0;
}
}
if(flag) p++;
}
}
void creat_column()
{
q=1;
bool flag;
for(int j=0; j<m; j++)
{
flag=0;
for(int i=0; i<n; i++)
{
if(ch[i][j]=='*')
{
b[i][j]=q;
flag=1;
}
if(ch[i][j]=='#')
{
q++;
flag=0;
}
}
if(flag) q++;
}
}
bool dfs(int x)
{
for(int i=1;i<q;i++)
{
if(!vis[i] && con[x][i])
{
vis[i]=1;
if(match[i]==-1 || dfs(match[i]))
{
match[i]=x;
return true;
}
}
}
return false;
}
void solve()
{
creat_row();
creat_column();
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(ch[i][j]=='*')
con[a[i][j]][b[i][j]]=1;
int cnt=0;
for(int i=1;i<p;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) cnt++;
}
printf("%d\n",cnt);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
initial();
input();
solve();
}
return 0;
}
hdu 5093 Battle ships (二部图+最大匹配)
标签:des style blog http io color ar os java
原文地址:http://blog.csdn.net/u012596172/article/details/40822543