POJ-2226-Muddy Fields

二分图匹配题,这个题是求用最少的木板把所有的低洼处填上。这个题构图个人觉得非常巧妙,首先对于每个低洼处,它不是横着木板覆盖就是竖着木板覆盖,那么这样的话我们可以把低洼横着和竖着进行编号(能用一个木板连接的编相同的号),然后对于每个低洼处横着和竖着的编号进行连边,然后就变成了求最少的点去覆盖这些所有的边~

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
const int maxn=55;
const int maxm=maxn*maxn;
int n,m,cnt,id[maxn][maxn],link[maxm];
char map[maxn][maxn];
vector<int> g[maxm];
bool vis[maxm];
void Init()
{
    memset(id,0,sizeof(id));
    memset(link,-1,sizeof(link));
    for(int i=0;i<=n*m;i++)
        g[i].clear();
}
bool find(int u)
{
    for(int i=0;i<g[u].size();i++)
        if(!vis[g[u][i]])
        {
            vis[g[u][i]]=1;
            if(link[g[u][i]]==-1||find(link[g[u][i]]))
            {
                link[g[u][i]]=u;
                return true;
            }
        }
    return false;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Init();
        for(int i=1;i<=n;i++)
            scanf("%s",map[i]+1);
        cnt=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                while(j<=m&&map[i][j]=='.')
                    j++;
                if(j<=m&&map[i][j]=='*')
                {
                    cnt++;
                    while(j<=m&&map[i][j]=='*')
                    {
                        id[i][j]=cnt;
                        j++;
                    }
                }
            }
        cnt=0;
        for(int j=1;j<=m;j++)
            for(int i=1;i<=n;i++)
            {
                while(i<=n&&map[i][j]=='.')
                    i++;
                if(i<=n&&map[i][j]=='*')
                {
                    cnt++;
                    while(i<=n&&map[i][j]=='*')
                    {
                        g[cnt].push_back(id[i][j]);
                        i++;
                    }
                }
            }
        int ans=0;
        for(int i=1;i<=cnt;i++)
        {
            memset(vis,0,sizeof(vis));
            if(find(i))
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(二分图)