思路:搞出所有横的和竖的联通块,然后两个联通块交点是*的话就连条边,直接二分图匹配即可。
PS:点数好多啊,空间开炸了,调了0.5H
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // It is made by XZZ 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 #define rep(a,b,c) for(rg int a=b;a<=c;a++) 6 #define drep(a,b,c) for(rg int a=b;a>=c;a--) 7 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a]) 8 #define il inline 9 #define rg register 10 #define vd void 11 typedef long long ll; 12 il int gi(){ 13 rg int x=0,f=1;rg char ch=getchar(); 14 while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar(); 15 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 16 return x*f; 17 } 18 const int maxn=1500,S=1498,T=1499,maxm=10000<<1; 19 int fir[maxn],dis[maxm],nxt[maxm],w[maxm],id=1; 20 char chess[55][55]; 21 il vd add(int a,int b,int ww){ 22 nxt[++id]=fir[a],dis[id]=b,w[id]=ww,fir[a]=id; 23 if(ww)add(b,a,0); 24 } 25 int dep[maxn]; 26 il bool BFS(){ 27 int que[maxn],hd=0,tl=1;bool vis[maxn]={0}; 28 que[0]=S,dep[S]=1,vis[S]=1; 29 while(hd^tl){ 30 int now=que[hd++]; 31 erep(i,now) 32 if(w[i]>0&&!vis[dis[i]]) 33 vis[dis[i]]=1,dep[dis[i]]=dep[now]+1,que[tl++]=dis[i]; 34 } 35 return vis[T]; 36 } 37 il int Dinic(int now,int rest){ 38 if(now==T)return rest; 39 int flow=rest; 40 erep(i,now) 41 if(w[i]>0&&w[i]<=rest&&dep[dis[i]]==dep[now]+1){ 42 int Flow=Dinic(dis[i],min(w[i],rest)); 43 w[i]-=Flow,w[i^1]+=Flow,rest-=Flow; 44 if(!rest)return flow; 45 } 46 return flow-rest; 47 } 48 int index[55][55][2]; 49 int main(){ 50 freopen("heoi2016_game.in","r",stdin); 51 freopen("heoi2016_game.out","w",stdout); 52 int n,m,num=0; 53 scanf("%d%d",&n,&m); 54 rep(i,1,n)scanf("%s",chess[i]+1); 55 rep(i,1,n)rep(j,1,m){ 56 if(chess[i][j]=='#')continue; 57 if(chess[i][j-1]=='#'||j==1)++num,add(S,num,1); 58 index[i][j][0]=num; 59 } 60 rep(j,1,m)rep(i,1,n){ 61 if(chess[i][j]=='#')continue; 62 if(chess[i-1][j]=='#'||i==1)++num,add(num,T,1); 63 index[i][j][1]=num; 64 } 65 rep(i,1,n)rep(j,1,m) 66 if(chess[i][j]=='*')add(index[i][j][0],index[i][j][1],1); 67 int flow=0; 68 while(BFS())flow+=Dinic(S,23333); 69 printf("%d ",flow); 70 return 0; 71 }