poj2226(最小点覆盖)

传送门:Muddy Fields

题意:一个由r行c列方格组成的田地,里面有若干个方格充满泥泞,其余方格都是草。要用长度不限,宽度为1的长木板来覆盖这些泥方格,但不能覆盖草地。最少要用多少个长木板。

分析:行列模型最小点覆盖,给连续行和列重新标号,然后每个字符*代表一条边,题目转换成用最少点覆盖所有的边(*)。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 1010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
int match[N],vis[N],n,m;
int vn,vm,r[N][N],c[N][N];
int g[N][N];
char s[N][N];
int dfs(int u)
{
    for(int i=1; i<=vm; i++)
    {
        if(g[u][i]&&!vis[i])
        {
            vis[i]=1;
            if(match[i]==-1||dfs(match[i]))
            {
                match[i]=u;
                return 1;
            }
        }
    }
    return 0;
}
int hungary()
{
    FILL(match,-1);
    int ans=0;
    for(int i=1; i<=vn; i++)
    {
        FILL(vis,0);
        if(dfs(i))ans++;
    }
    return ans;
}
void build()
{
    vn=vm=0;FILL(g,0);
    for(int i=1; i<=n; i++)
    {
        int first=1;
        for(int j=1; j<=m; j++)
        {
            if(s[i][j]=='*')
            {
                if(first)vn++;
                first=0;
                r[i][j]=vn;
            }
            else first=1;
        }
    }
    for(int i=1;i<=m;i++)
    {
        int first=1;
        for(int j=1; j<=n; j++)
        {
            if(s[j][i]=='*')
            {
                if(first)vm++;
                first=0;
                c[j][i]=vm;
            }
            else first=1;
        }
    }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            if(s[i][j]=='*')
            {
                g[r[i][j]][c[i][j]]=1;
            }
}
int main()
{
    while(scanf("%d%d",&n,&m)>0)
    {
        for(int i=1; i<=n; i++)
            scanf("%s",s[i]+1);
        build();
        int res=hungary();
        printf("%d
",res);
    }
}
View Code
原文地址:https://www.cnblogs.com/lienus/p/4287752.html