• [luogu2825 HEOI2016/TJOI2016] 游戏 (二分图最大匹配)


    传送门

    Description

    在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂。简单的说,这个游戏就是在一张地图上放上若干个炸弹,看是否能炸到对手,或者躲开对手的炸弹。在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透软石头,但是不能穿透硬石头。给定一张nm的网格地图:其中代表空地,炸弹的威力可以穿透,可以在空地上放置一枚炸弹。x代表软石头,炸弹的威力可以穿透,不能在此放置炸弹。#代表硬石头,炸弹的威力是不能穿透的,不能在此放置炸弹。例如:给出14的网格地图xx,这个地图上最多只能放置一个炸弹。给出另一个14的网格地图x#,这个地图最多能放置两个炸弹。现在小H任意给出一张n*m的网格地图,问你最多能放置多少炸弹。

    Input

    第一行输入两个正整数n,m,n表示地图的行数,m表示地图的列数。1≤n,m≤50。接下来输入n行m列个字符,代表网格地图。的个数不超过nm个。

    Output

    输出一个整数a,表示最多能放置炸弹的个数

    Sample Input

    4 4
    #∗∗∗
    ∗#∗∗
    ∗∗#∗
    xxx#
    

    Sample Output

    5

    Solution

    实际上就是互相影响的不能同时选择
    把图按照块编号后跑最大匹配

    Code

    //By Menteur_Hxy
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    #define E(i,u) for(register int i=head[u];i;i=nxt[i])
    #define ins(a,b,c) add(a,b,c),add(b,a,0)
    #define add(a,b,c) nxt[++cnt]=head[a],to[cnt]=b,cst[cnt]=c,head[a]=cnt
    using namespace std;
    
    int read() {
    	int x=0,f=1; char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=1010,INF=0x3f3f3f3f;
    int n,m,xid,yid,S,T,cnt;
    int nxt[N*N],to[N*N],cst[N*N],head[N*N],cur[N*N];
    int map[N][N],dx[N][N],dy[N][N],que[N*N<<2],dis[N*N];
    
    bool bfs() {
    	memset(dis,0,sizeof(dis));
    	int h=0,t=1; que[++h]=S; dis[S]=1;
    	while(h<=t) {
    		int u=que[h++];
    		E(i,u) if(!dis[to[i]]&&cst[i]>0)
    			dis[to[i]]=dis[u]+1,que[++t]=to[i];
    	}
    	return dis[T];
    }
    
    int dfs(int u,int flow) {
    	if(u==T) return flow;
    	int used=0;
    	for(register int &i=cur[u],v;i;i=nxt[i]) 
    		if(cst[i]>0&&dis[(v=to[i])]==dis[u]+1) {
    			int tmp=dfs(v,min(flow-used,cst[i]));
    			cst[i]-=tmp,cst[i^1]+=tmp;
    			used+=tmp; if(used==flow) return flow;
    		}
    	if(!used) dis[u]=-1;
    	return used;	
    }
    
    int dinic() {
    	int res=0;
    	while(bfs()) {
    		F(i,0,T) cur[i]=head[i];
    		res+=dfs(S,INF);
    	}
    	return res;
    }
    
    int main() {
    	n=read(),m=read();
    	F(i,1,n) {
    		scanf("
    ");
    		F(j,1,m) {
    			char ch=getchar();
    			if(ch=='x') map[i][j]=1;
    			else if(ch=='#') map[i][j]=2;
    		}
    	}
    	F(i,1,n) {
    		xid++;
    		F(j,1,m) 
    			dx[i][j]=xid,xid+=(map[i][j]==2);
    	}
    	F(i,1,m) {
    		yid++;
    		F(j,1,n) 
    			dy[j][i]=yid,yid+=(map[j][i]==2);
    	}
    	S=0,T=xid+yid+1,cnt=1;
    	F(i,1,xid) ins(S,i,1); F(i,1,yid) ins(i+xid,T,1);
    	F(i,1,n) F(j,1,m) if(!map[i][j]) 
    		ins(dx[i][j],dy[i][j]+xid,1);
    	printf("%d",dinic());
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    跟着太白老师学python 10day 函数的动态参数 *args, **kwargs, 形参的位置顺序
    IO 流之字符流的缓冲区
    Java IO异常处理方式
    Java IO 流
    Java 其他对象的 API
    Java 集合框架之 JDK 1.5 新特性
    Java 集合框架工具类
    Java 集合框架之 Map
    Java 集合框架查阅技巧
    Java 集合框架之泛型
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9485463.html
Copyright © 2020-2023  润新知