hdu4185-Oil Skimming(二分图,模板)

来源:互联网 发布:linux安装输入法 编辑:程序博客网 时间:2024/05/21 21:02

题目来源:http://a/showproblem.php?pid=4185

题意

给出一个由’.’和’#’构成的矩阵,#代表油田,为10*10,问,每次挖10*20的油田,最多挖几次。

思路

这道题思路很简单,给每个油田编号,然后把它四周有关系的标记,然后问题就转化成了两两匹配,最多能匹配多少组,那么1和2是一组,2和1也是一组,所以,最后结果要除以2。
这道题证明了一个问题,在深搜的过程中去除vis标记,与在外面统一清0是不一样的。也就是说在里面vis[j]=0是可能会有漏洞的,先记下,,,(因为找不出数据),默默记下。。。(让我wa到怀疑人生)

代码

#include<vector>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=600+10;char str[maxn][maxn];int mp[maxn][maxn],num[maxn][maxn];int pre[maxn],vis[maxn];int n,tot,cases;void init(){    tot=0;    scanf("%d",&n);    memset(num,0,sizeof(num));    memset(str,0x00,sizeof(str));    for(int i=1; i<=n; i++)    {        scanf("%s",str[i]+1);        for(int j=1; j<=n; j++)            if(str[i][j]=='#')                num[i][j]=++tot;    }    memset(mp,0,sizeof(mp));}void deal(){    for(int i=1; i<=n; i++)    {        for(int j=1; j<=n; j++)        {            if(str[i][j]=='#')            {                if(i!=1&&str[i-1][j]=='#') mp[num[i][j]][num[i-1][j]]=1;                if(j!=1&&str[i][j-1]=='#') mp[num[i][j]][num[i][j-1]]=1;                if(i!=n&&str[i+1][j]=='#') mp[num[i][j]][num[i+1][j]]=1;                if(j!=n&&str[i][j+1]=='#') mp[num[i][j]][num[i][j+1]]=1;            }        }    }}int dfs(int i){    for(int j=1; j<=tot; j++)    {        if(mp[i][j]&&!vis[j])        {            vis[j]=1;            if(pre[j]==-1||dfs(pre[j]))            {                pre[j]=i;                return 1;            }        }    }    return 0;}void solve(){    int ret=0;    memset(pre,-1,sizeof(pre));    for(int i=1; i<=tot; i++)    {        memset(vis,0,sizeof(vis));        ret+=dfs(i);    }    printf("Case %d: %d\n",++cases,ret/2);}int main(){    int T;    cases=0;    scanf("%d",&T);    while(T--)    {        init();        deal();        solve();    }}
原创粉丝点击