HDU 1281 棋盘游戏 (二分图+枚举每点是否为匹配关键)

思路:容易看出是二分图的最大匹配问题,但是如何判断某点是否为关键点是关键。我们可以将每个可能的点枚举一下

然后进行删点,判断删点后的最大匹配是否仍等于原来的最大匹配即可。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int head[1000],cropath[1000],s,a[1000],b[1000],n;
bool use[1000],Map[1000][1000];
int pre[1000];
int DFS(int v)
{
    int i,j,k;
    for(i=1; i<=n; i++)
        if(!use[i]&&Map[v][i])
        {
            use[i]=true;
            if(cropath[i]==-1||DFS(cropath[i]))
            {
                cropath[i]=v;
                return 1;
            }
        }
    return 0;
}
int main()
{
    int m,i,j,k,cla=1;
    while(~scanf("%d%d%d",&m,&n,&k))
    {
        memset(cropath,-1,sizeof(cropath));
        memset(Map,false,sizeof(Map));
        for(i=0; i<k; i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            Map[a[i]][b[i]]=true;
        }
        printf("Board %d have ",cla++);
        int ans=0;
        for(i=1; i<=m; i++)
        {
            memset(use,false,sizeof(use));
            if(DFS(i))
                ans++;
        }
        int z=0,tmp;
        for(i=0; i<k; i++)
        {
            tmp=0;
            if(Map[a[i]][b[i]])
            {
                memset(cropath,-1,sizeof(cropath));
                Map[a[i] ][b[i] ]=false;
                for(int p=1;p<=m; p++)
                {
                    memset(use,false,sizeof(use));
                    tmp+=DFS(p);
                }
                Map[a[i] ][b[i]]=true;
                if(ans!=tmp)
                    z++;
            }
        }
        printf("%d important blanks for %d chessmen.\n",z,ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值