【bzoj 4554】【Tjoi2016&Heoi2016】【NOIP2016模拟7.12】游戏

来源:互联网 发布:dangerouspeople淘宝 编辑:程序博客网 时间:2024/06/05 06:44

题目

这里写图片描述

分析

当没有石头的时候,就用二分图匹配来做。
但现在加入了石头,
所以,求出每行和每列联通快的个数,如果有一块平地,包括在某个行联通块以及某个列联通块中,连边。

//无聊打了网络流,匈牙利也可以#include <cmath>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <queue>const int maxlongint=2147483647;const int mo=1000000007;const int N=54;using namespace std;int n,m,a[N][N],ans,tot,f[N*N+6][N*N+6],id,v[N*N+6],t;int b[N][N];int aug(int x,int y){    if(x==n*m+n) return y;    v[x]=id;    for(int i=0;i<=n*m+n;i++)    {        if(f[x][i] && v[i]<id)        {            int o=aug(i,min(y,f[x][i]));            if(o)            {                f[x][i]-=o;                f[i][x]+=o;                return o;            }        }    }    return 0;}                           int main(){    scanf("%d%d",&n,&m);    tot=0;    for(int i=1;i<=n;i++)    {        tot++;        for(int j=1;j<=m;j++)        {            char c;            c=getchar();            while(c!='*' && c!='x' && c!='#') c=getchar();            if(c=='*') a[i][j]=1;            else                if(c=='x') a[i][j]=2;                    else                        a[i][j]=3;            if(a[i][j]==3 && a[i][j-1]!=3) tot++;            else            {                f[0][tot]=1;                b[i][j]=tot;            }        }    }    for(int i=1;i<=m;i++)    {        tot++;        for(int j=1;j<=n;j++)        {            if(a[j][i]==3) tot++;            else            {                if(a[j][i]!=2) f[b[j][i]][tot]=1;                f[tot][n*m+n]=1;            }        }    }    t=1;    while(t)    {        id++;        t=aug(0,maxlongint);        ans+=t;         }    printf("%d",ans);}
1 0
原创粉丝点击