首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【BZOJ4554】【TJOI2016】【HEOI2016】游戏

我好弱啊quq

原题:

在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看
是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张
地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一
列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张n*m的网格地图:其中*代表空地,炸弹的威力可
以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸
弹的威力是不能穿透的,不能在此放置炸弹。例如:给出1*4的网格地图*xx*,这个地图上最多只能放置一个炸弹
。给出另一个1*4的网格地图*x#*,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最
多能放置多少炸弹
1≤n,m≤50
 
经典二分图匹配魔性(但是我不知道quq
这题如果没有硬石头的话就对于每个空地(x,y)连x->y的边搞二分图匹配
这题有硬石头就相当于对于每个x或y分成了几组,扫一下记录每个点的x和y对应的组然后二分图即可
代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int oo=168430090;
 8 int rd(){int z=0,mk=1;  char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
11     return z*mk;
12 }
13 struct ddd{int nxt,y,v,rvs;}e[2100000];  int lk[3100],ltp=0;
14 inline void ist(int x,int y,int z){
15     e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y,e[ltp].v=z,e[ltp].rvs=ltp+1;
16     e[++ltp].nxt=lk[y],lk[y]=ltp,e[ltp].y=x,e[ltp].v=0,e[ltp].rvs=ltp-1;
17 }
18 int n,m;  char a[110][110];  int s,t;
19 int idx[110][110],idy[110][110],tt=0,quq=0;
20 int lvl[3100];
21 int q[3100],hd=0;
22 bool gtlvl(){
23     memset(lvl,0,sizeof(lvl));
24     q[hd=1]=s,lvl[s]=1;
25     for(int k=1;k<=hd;++k)for(int i=lk[q[k]];i;i=e[i].nxt)
26         if(e[i].v && !lvl[e[i].y])  lvl[e[i].y]=lvl[q[k]]+1,q[++hd]=e[i].y;
27     return lvl[t];
28 }
29 int mxflw(int x,int y){
30     if(x==t)  return y;
31     int bwl=0,flw;
32     for(int i=lk[x];i && bwl<y;i=e[i].nxt)if(e[i].v && lvl[e[i].y]==lvl[x]+1)
33         if((flw=mxflw(e[i].y,min(y-bwl,e[i].v))))
34             bwl+=flw,e[i].v-=flw,e[e[i].rvs].v+=flw;
35     if(!bwl)  lvl[x]=0;
36     return bwl;
37 }
38 int dnc(){
39     int bwl=0,flw;
40     while(gtlvl())while((flw=mxflw(s,oo)))  bwl+=flw;
41     return bwl;
42 }
43 int main(){//freopen("ddd.in","r",stdin);
44     cin>>n>>m;
45     for(int i=1;i<=n;++i)  scanf("%s",a[i]+1);
46     for(int i=1;i<=n;++i){
47         a[i][m+1]=a[i][0]='#';
48         for(int j=0;j<=m;++j){
49             if(a[i][j]=='#' && a[i][j+1]!='#')  ++tt;
50             else  if(a[i][j]!='#')  idx[i][j]=tt;
51         }
52     }
53     quq=tt;
54     for(int i=1;i<=m;++i){
55         a[n+1][i]=a[0][i]='#';
56         for(int j=0;j<=n;++j){
57             if(a[j][i]=='#' && a[j+1][i]!='#')  ++tt;
58             else  if(a[j][i]!='#')  idy[j][i]=tt;
59         }
60     }
61     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(a[i][j]=='*')
62         ist(idx[i][j],idy[i][j],1);
63     s=0,t=tt+1;
64     for(int i=1;i<=quq;++i)  ist(s,i,1);
65     for(int i=quq+1;i<=tt;++i)  ist(i,t,1);
66     /*for(int i=1;i<=n;++i){
67         for(int j=1;j<=m;++j)  cout<<idx[i][j]<<" ";
68         cout<<endl;
69     }
70     cout<<endl;
71     for(int i=1;i<=n;++i){
72         for(int j=1;j<=m;++j)  cout<<idy[i][j]<<" ";
73         cout<<endl;
74     }
75     for(int i=s;i<=t;++i)
76         for(int j=lk[i];j;j=e[j].nxt)
77             cout<<i<<"->"<<e[j].y<<" "<<e[j].v<<endl;*/
78     cout<<dnc()<<endl;
79     return 0;
80 }
View Code

 

posted on 2017-03-16 14:53  cdcq_old  阅读(207)  评论(0编辑  收藏  举报