BZOJ 4554 [Tjoi2016&Heoi2016]游戏 ——二分图

出原题,直接二分图匹配即可。

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
 
vector <int> v[3005];
 
int n,m,map[55][55],mx,ans;
int le[55][55],ri[55][55],vis[3005],linker[3005];
char s[55];
 
bool dfs(int o)
{
    for (int i=0;i<v[o].size();++i)
    if (!vis[v[o][i]]){
        vis[v[o][i]]=1;
        if (!linker[v[o][i]]||dfs(linker[v[o][i]]))
        {
            linker[v[o][i]]=o;
            return true;
        }
    }
    return false;
}
 
int main()
{
    scanf("%d%d",&n,&m);
    F(i,1,n)
    {
        scanf("%s",s+1);
        F(j,1,m)
            switch(s[j])
            {
                case '*': map[i][j]=1;break;
                case '#': map[i][j]=-1;break;
                case 'x': map[i][j]=0;break;
            }
    }
    F(i,0,n+1) map[i][0]=map[i][m+1]=-1;
    F(i,0,m+1) map[n+1][i]=map[0][i]=-1;
    int cnt=0,con=1;
    F(i,0,n) F(j,0,m)
        if (map[i][j]!=-1) con=1,le[i][j]=cnt;
        else{if (con) ++cnt,con=0;}
    mx=cnt;cnt=0,con=1;
    F(j,0,m) F(i,0,n)
        if (map[i][j]!=-1) con=1,ri[i][j]=cnt;
        else {if (con) ++cnt,con=0;}
    F(i,1,n) F(j,1,m)
        if (map[i][j]==1)
            v[le[i][j]].push_back(ri[i][j]);
    F(i,1,mx)
    {
        memset(vis,0,sizeof vis);
        if (dfs(i)) ans++;
    }
    printf("%d\n",ans);
}

  

posted @ 2017-04-20 11:24  SfailSth  阅读(134)  评论(0编辑  收藏  举报