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

来源:互联网 发布:凌虚剑淘宝 编辑:程序博客网 时间:2024/06/05 04:25

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

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


#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;}


0 0
原创粉丝点击