【HEOI2016】游戏 二分图

来源:互联网 发布:最新编程语言排行 编辑:程序博客网 时间:2024/06/05 06:10

题目描述

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

题目大意

  求在地图上最多放置多少个炸弹不能互相攻击(如果两个炸弹在同一行或同一列且之间没有硬石头就能互相攻击)

数据范围

1≤n,m≤50

样例输入

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

样例输出

5

解题思路

二分图最大匹配。

代码

#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>using namespace std;inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}int Map[205][205],h[205][205],s[205][205],f[40005][233],my[40005],vis[40005],cnth=0,cnts=0;bool dfs(int x){    for(int i=1;i<=f[x][0];i++){        int y=f[x][i];        if(!vis[y]){            vis[y]=1;            if(!my[y]||dfs(my[y])){                my[y]=x;                return true;            }        }    }    return false;}inline char Getch(){    char ch=getchar();    while(ch!='x'&&ch!='#'&&ch!='*')ch=getchar();    return ch;}inline int ff(char x){    if(x=='x')return 1;    if(x=='#')return 2;    return 0;}int main(){    int m=Getint(),n=Getint(),Ans=0;    for(int i=1;i<=m;i++)        for(int j=1;j<=n;j++){            Map[i][j]=ff(Getch());        }    for(int i=0;i<=m+1;i++)Map[i][0]=Map[i][n+1]=2;    for(int j=0;j<=n+1;j++)Map[0][j]=Map[m+1][j]=2;    for(int i=1;i<=m;i++)        for(int j=1;j<=n;j++)            if(Map[i][j]!=2)                if(Map[i][j-1]==2)h[i][j]=++cnth;                else h[i][j]=cnth;    for(int j=1;j<=n;j++)        for(int i=1;i<=m;i++)            if(Map[i][j]!=2)                if(Map[i-1][j]==2)s[i][j]=++cnts;                else s[i][j]=cnts;    for(int i=1;i<=m;i++)        for(int j=1;j<=n;j++)            if(!Map[i][j])                f[h[i][j]][++f[h[i][j]][0]]=s[i][j];    memset(my,0,sizeof(my));    for(int i=1;i<=cnth;i++){        memset(vis,0,sizeof(vis));        Ans+=dfs(i);    }    cout<<Ans;    return 0;}
0 0
原创粉丝点击