【bzoj4554】【Tjoi2016】【Heoi2016】【游戏】【二分图匹配】
2016-07-12 19:25
381 查看
题目大意
给出一个图,有一些石头不可炸,一些软石头可炸但不可放炸弹,一些空地可放炸弹。用最多炸弹使两个炸弹互相不可炸。
题解
对于横竖连通的块标号,可放炸弹的点横竖相连,表示可以放炸弹,做二分图最大匹配即可。
code
#include<set> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) using namespace std; int const maxn=50; int n,m,a[maxn+10][maxn+10],to[maxn*maxn+10][maxn*maxn+10],pai[maxn*maxn+10]; bool done[maxn*maxn+10]; char ch[maxn+10][maxn+10]; bool match(int now){ fo(i,1,to[now][0]) if(!done[to[now][i]]){ done[to[now][i]]=1; if((!pai[to[now][i]])||(match(pai[to[now][i]]))){ pai[to[now][i]]=now; return 1; } } return 0; } int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%d%d\n",&n,&m); fo(i,1,n){ fo(j,1,m)scanf("%c",&ch[i][j]); scanf("\n"); } int cnt=0; fo(i,1,n) fo(j,1,m){ if((ch[i][j]!='#')&&((ch[i][j-1]=='#')||(j==1)))cnt++; a[i][j]=cnt; } int cnt2=cnt; fo(j,1,m) fo(i,1,n){ if((ch[i][j]!='#')&&((ch[i-1][j]=='#')||(i==1)))cnt2++; if(ch[i][j]=='*')to[a[i][j]][++to[a[i][j]][0]]=cnt2; } int ans=0; fo(i,1,cnt){ if(match(i))ans++; memset(done,0,sizeof(done)); } printf("%d",ans); return 0; }
相关文章推荐
- cf 102 A(暴力)
- 错误信息:Address already in use: connect
- 使用virtualenv独立python环境
- ajax返回object Object解决方法
- leetcode343 Integer Break java
- 内存映射文件处理大文件
- 【Tjoi2016&Heoi2016】排序
- socket连接库,兼容ipv6,ipv4,为IOS上架做准备
- 输入输出流
- hdu1503 -Advanced Fruits
- 错题集锦(三)
- 剑指offer 牛客网错题记录 四
- 7. ubuntu 16.04 LTS 安装模块儿fastdfs-nginx-module
- cf 437 D(并查集)
- 有什么值得一看的燃到爆的电影?
- JNI
- Android 高仿猎豹cm桌面,所有应用,快捷字母栏
- uwa渲染模块性能
- ACM集训day2
- android developer tiny share-20160712