HDU 1045

二分图匹配

题意:给你一个矩阵,X所在的地方是墙,往上面放碉堡,碉堡所在的行和列上的所有的点消灭掉。

与最简单的二分图不同的是,有墙。

做二分图的题,第一步要建图,在这里,二分图是一条边的两端分处于不同的点集、所以每找到一个点就把和他同一行、同一列的点都做同样的标记。遇到墙就停下

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define N 8
int cnt_row, cnt_col;
int row[N][N], col[N][N], r[N], c[N];
char map[N][N];
bool path[N][N], vis[N];

int dfs(int rr)
{
    for(int i=0;i<cnt_col;++i)
    {
        if(path[rr][i]&&vis[i]==false)
        {
            vis[i]=true;
            if(c[i]==-1||dfs(c[i]))
            {
                c[i]=rr;
                r[rr]=i;
                return 1;
            }
        }
    }
    return 0;
}
int maxmatch()
{
    int ans=0;
    memset(r,-1,sizeof(r));
    memset(c,-1,sizeof(c));
    for(int i=0;i<cnt_row;i++)
    {
        if(r[i]==-1)
        {
            memset(vis,false,sizeof(vis));
            ans+=dfs(i);
        }
    }
    return ans;
}
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        for(int i = 0; i < n; ++i)
        {
            scanf("%s",map[i]);
        }
        memset(row,-1,sizeof(row));
        memset(col,-1,sizeof(col));
        cnt_row=cnt_col=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(map[i][j]=='.'&&row[i][j]==-1)
                {
                    for(int k=j;map[i][k]=='.'&&k<n;++k)
                    {
                        row[i][k]=cnt_row;
                    }
                    cnt_row++;
                }
                if(map[j][i]=='.'&&col[j][i]==-1)
                {
                    for(int k=j;map[k][i]=='.'&&k<n;++k)
                    {
                        col[k][i]=cnt_col;
                    }
                    cnt_col++;
                }
            }
        }
        memset(path,false,sizeof(path));
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<n;++j)
            {
                if(map[i][j]=='.')
                {
                    path[row[i][j]][col[i][j]]=true;
                }
            }
        }
        printf("%d
",maxmatch());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/qioalu/p/5445562.html