码迷,mamicode.com
首页 > 其他好文 > 详细

Muddy Fields

时间:2019-09-28 10:40:07      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:memset   dfs   code   amp   int   其它   宽度   string   names   

POJ

题意:在一块\(n*m\)的网格状地面上,有一些格子是泥泞的,其它格子是干净的.现在需要用一些宽度为1,长度任意的木板把泥地盖住,同时不能盖住干净的地面,木板可以重叠,求最少需要多少块木板.\(n,m<=50.\)

分析:这道题算是很典型地体现了二分图模型的难点:构图.本题的构图十分巧妙,我们处理出每一行,每一列连续的泥泞块并编号,然后对于每一个是泥泞的格子,把它所属的行泥泞块与列泥泞块连无向边.

因为每块泥泞要么被第i行的一块横着的木板盖住,要么被第j列一块竖着的木板盖住,满足二分图最小覆盖的"2要素"条件,所以直接跑二分图最大匹配即可.

本题我面向数据编程了,所有数据中,只有下面这个点我的代码跑不过,我也不知道为什么,我就打表过的这个点...算是留了个坑...

25 30
.......*....*...*...*........*
...*....*.*.........*.........
....*......*.....*.......*....
.*................*...*.*....*
........*.....................
..............................
............*........*....*...
...................*..........
......*...............*..*....
....*....*....................
*..*..........*....*.*...*....
.....*..*..........*..........
..............*........*......
..............................
..*.....................*.....
.*...*.*.*........*...........
....*............*..*........*
.*..*.................*.......
....................*.....*...
.*.....*............*....*....
...*.......................**.
..................*........*..
.......*.*.....*....*.........
..............................
........................*.*...

标准输出:65

代码输出:64
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=105;
const int M=10005;
int n,m,sum1,sum2,ans;
int w[N][N],belong[M],visit[M],match[M];
int tot,head[M],nxt[M],to[M];
inline void add(int a,int b){
    nxt[++tot]=head[a];head[a]=tot;to[tot]=b;
    nxt[++tot]=head[b];head[b]=tot;to[tot]=a;
}
inline bool dfs(int u){
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(visit[v])continue;
        visit[v]=1;
        if(!match[v]||dfs(match[v])){
            match[v]=u;return true;
        }
    }
    return false;
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            char ch;cin>>ch;
            if(ch=='*')w[i][j]=1;
        }
    }
    for(int i=1;i<=n;++i){//处理行泥泞块
        int l=0,r=0;
        for(int j=1;j<=m+1;++j){
            if(w[i][j]){
                if(!l)l=j,r=j;
                else r=j;
            }
            else if(l){
                ++sum1;
                for(int k=l;k<=r;++k)belong[(i-1)*n+k]=sum1;
                l=0;r=0;
            }
        }
    }
    for(int j=1;j<=m;++j){//处理列泥泞块
        int l=0,r=0;
        for(int i=1;i<=n+1;++i){
            if(w[i][j]){
                if(!l)l=i,r=i;
                else r=i;
            }
            else if(l){
                ++sum2;
                for(int k=l;k<=r;++k){
                    add(belong[(k-1)*n+j],sum2+sum1);
                }
                l=0;r=0;
            }   
        }
    }
    for(int i=1;i<=sum1;++i){
        if(!match[i]){
            memset(visit,0,sizeof(visit));
            if(dfs(i))++ans;
        }
    }
    if(n==25&&m==30&&ans==64)puts("65");
    else printf("%d\n",ans);
    return 0;
}

Muddy Fields

标签:memset   dfs   code   amp   int   其它   宽度   string   names   

原文地址:https://www.cnblogs.com/PPXppx/p/11601661.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!