我是靠谱客的博主 留胡子金鱼,这篇文章主要介绍【bzoj4554】【Tjoi2016】【Heoi2016】【游戏】【二分图匹配】,现在分享给大家,希望可以做个参考。

题目大意

给出一个图,有一些石头不可炸,一些软石头可炸但不可放炸弹,一些空地可放炸弹。用最多炸弹使两个炸弹互相不可炸。

题解

对于横竖连通的块标号,可放炸弹的点横竖相连,表示可以放炸弹,做二分图最大匹配即可。

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%dn",&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;
}

最后

以上就是留胡子金鱼最近收集整理的关于【bzoj4554】【Tjoi2016】【Heoi2016】【游戏】【二分图匹配】的全部内容,更多相关【bzoj4554】【Tjoi2016】【Heoi2016】【游戏】【二分图匹配】内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部