zoukankan      html  css  js  c++  java
  • [HEOI2016/TJOI2016]游戏

    Description:

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

    Hint:

    (n,m le 50)

    Solution:

    考虑怎么处理硬石头,其实很简单,把原图的行列拆成很多连续子串作为新的行列,这样就可以直接跑二分图行列模型了

    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ls p<<1 
    #define rs p<<1|1
    using namespace std;
    typedef long long ll;
    const int mxn=1e5+5,inf=1e9;
    int n,m,S,T,cnt,tot,ans,id1[55][55],id2[55][55],hd[mxn],cur[mxn],dep[mxn];
    char a[55][55];
    
    inline int read() {
    	char c=getchar(); int x=0,f=1;
    	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    	return x*f;
    }
    inline void chkmax(int &x,int y) {if(x<y) x=y;}
    inline void chkmin(int &x,int y) {if(x>y) x=y;}
    
    struct ed {
    	int to,nxt,w;
    }t[mxn<<1];
    
    inline void add(int u,int v,int w) {
    	t[cnt]=(ed) {v,hd[u],w}; hd[u]=cnt++;
    	t[cnt]=(ed) {u,hd[v],0}; hd[v]=cnt++;
    }
    
    int bfs() {
    	memset(dep,0,sizeof(dep));
    	queue<int > q; dep[S]=1;
    	q.push(S);
    	for(int i=0;i<=T;++i) cur[i]=hd[i];
    	while(!q.empty()) {
    		int u=q.front(); q.pop();
    		for(int i=hd[u];i!=-1;i=t[i].nxt) {
    			int v=t[i].to;
    			if(t[i].w>0&&!dep[v]) 
    				dep[v]=dep[u]+1,q.push(v);
    		}
    	}
    	return dep[T];
    }
    
    int dfs(int u,int f) {
    	if(u==T) return f;
    	for(int &i=cur[u];i!=-1;i=t[i].nxt) {
    		int v=t[i].to;
    		if(t[i].w>0&&dep[v]==dep[u]+1) {
    			int tp=dfs(v,min(t[i].w,f));
    			if(tp>0) {
    				t[i].w-=tp;
    				t[i^1].w+=tp;
    				return tp;
    			}
    		}
    	}
    	return 0;
    }
    
    void Dinic() {
    	while(bfs()) 
    		while(int tp=dfs(S,inf))
    			ans+=tp;
    }
    
    int get(int x,int y) {
    	return (x-1)*m+y;
    }
    
    int main()
    {
    	n=read(); m=read(); T=n*m+n*m+1; memset(hd,-1,sizeof(hd));
    	for(int i=1;i<=n;++i) 
    		for(int j=1;j<=m;++j) 
    			cin>>a[i][j];
    	for(int i=1;i<=n;++i) 
    		for(int j=1;j<=m;++j) {
    			if(a[i][j]=='#') continue ;
    			if(j==1||a[i][j-1]=='#') ++tot,add(S,tot,1);
    			id1[i][j]=tot;
    		}
    	for(int j=1;j<=m;++j)
    		for(int i=1;i<=n;++i) {
    			if(a[i][j]=='#') continue ;
    			if(i==1||a[i-1][j]=='#') ++tot,add(tot,T,1);
    			id2[i][j]=tot;
    		}
    	for(int i=1;i<=n;++i) 
    		for(int j=1;j<=m;++j) {
    			if(a[i][j]!='*') continue ;
    			add(id1[i][j],id2[i][j],1);
    		} 
    	Dinic(); printf("%d",ans);	
        return 0;
    }
    
    
  • 相关阅读:
    解决Mac开机变慢 command +option + P + R
    Mac iphone 使用 如何修改apple 用户名 XXX的mac Mac 与iphone如何连接 传递文件 为iphone增加铃声 iphone铃声的制作---城
    Xcode7 iOS9.0 的真机调试
    苹果电脑Mac OS系统重装图文详解
    关闭自动弹出照片自动弹出iTunes以及关闭手机照片流
    mac 使用清除废纸篓或彻底删除某文件 附加: smb afp ftp NAS 访问服务器相关
    辨别苹果数据线真伪 苹果计算器 Dashboard 知识
    使用OC swift 截取路径中的最后的文件名
    升级OS10.11系统后 Xcode6.4的变化少了个按钮 could not launch “Xcode” Xcode 插件安装
    如何在苹果官网下载旧版本的Xcode
  • 原文地址:https://www.cnblogs.com/list1/p/10619084.html
Copyright © 2011-2022 走看看