标签: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