HDU 1045 二分图匹配

建图过程 主要是行列匹配的思想行列式独立的
先按行记录每个区域的车能走的左边界和右边界把这个左边界和右边界进行编号为c
再按列记录每个区域的车能走的上边界和下边界把这两个边界之间的点编号为e
然后遍历图的大小对于每个点link[c][e] = 1;
建图完毕

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define maxn 20
using namespace std;
char mp[maxn][maxn];
int link[maxn][maxn],used[maxn],id1[maxn][maxn],flag[maxn],id2[maxn][maxn];
int n,rCnt,cCnt;
bool dfs(int x)
{
     for(int i=1;i<=cCnt;i++)
         if(link[x][i]&&!used[i])
         {
            used[i] = true;
            if(flag[i]==0||dfs(flag[i]))
            {
               flag[i] = x;
               return true;
            }
         }
     return false;
}
int match()
{
    int ans = 0;
    memset(flag,0,sizeof(flag));
    for(int i=1;i<=rCnt;i++)
    {
        memset(used,0,sizeof(used));
        ans += dfs(i);
    }
    return ans;
}
int main()
{
    while(scanf("%d",&n)&&n)
    {
        rCnt = 0,cCnt = 0;
        memset(link,0,sizeof(link));
        memset(id1,0,sizeof(id1));
        memset(id2,0,sizeof(id2));
        for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);

        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(mp[i][j]=='.')
                {
                    if(j-1==0||mp[i][j-1]=='X') rCnt++;
                    id1[i][j] = rCnt;
                }

        for(int j=1;j<=n;j++)
            for(int i=1;i<=n;i++)
                if(mp[i][j]=='.')
                {
                    if(i-1==0||mp[i-1][j]=='X')cCnt++;
                    id2[i][j] = cCnt;
                }

        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                link[id1[i][j]][id2[i][j]] = true;
        printf("%d\n",match());
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值