【HEOI2016】遊戲 二分圖

題目描述

  在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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章