• Muddy Fields


    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
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    KLSudoku的数独题目生成方法和难度控制说明
    对XChain和ForcingChain的实现解说
    开源数独游戏软件KLSudoku发布第一个Release版本
    每个 Vim 用户都应该阅读的文章
    自己常用的几个gvim的vimrc设置
    KLSudoku数独游戏软件1.1预览版发布
    KLSudoku数独游戏软件1.1正式版发布
    字符串
    .NET面试大全
    IIS是如何处理ASP.NET请求的
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11601661.html
Copyright © 2020-2023  润新知