codevs 3052 多米诺 二分图匹配

Posted 一入OI深似海

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 3052 多米诺 二分图匹配相关的知识,希望对你有一定的参考价值。

/*codevs 3052 二分图匹配 把矩阵分两批 黑和白 且黑白不相交 这就构成了二分图的两部分 然后求最大匹配*/
#include<cstdio>
#include<cstring>
#define maxn 5010
using namespace std;
int n,m,k,num,head[maxn],match[maxn],ans;
int g[51][51],f[maxn],Color[51][51];
struct node{
    int v,pre;
}e[maxn];
int Cal(int x,int y){
    return (x-1)*m+y;
}
void Add(int from,int to){
    num++;e[num].v=to;
    e[num].pre=head[from];
    head[from]=num;
}
int Dfs(int u){
    for(int i=head[u];i;i=e[i].pre){
        int v=e[i].v;
        if(f[v])continue;f[v]=1;
        if(match[v]==0||Dfs(match[v])){
            match[v]=u;return 1;
        }
    }
    return 0;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        g[x][y]=1;
    }
    int cnt;
    for(int i=1;i<=n;i++){
        cnt=i&1;
        for(int j=1;j<=m;j++){
            cnt++;
            if(cnt&1)Color[i][j]=1;
            else Color[i][j]=0;
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            if(g[i][j]||Color[i][j])continue;
            if(j<m&&!g[i][j+1])Add(Cal(i,j),Cal(i,j+1));
            if(j>1&&!g[i][j-1])Add(Cal(i,j),Cal(i,j-1));
            if(i<n&&!g[i+1][j])Add(Cal(i,j),Cal(i+1,j));
            if(i>1&&!g[i-1][j])Add(Cal(i,j),Cal(i-1,j));
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
        if(g[i][j]||Color[i][j])continue;
        memset(f,0,sizeof(f));
        ans+=Dfs(Cal(i,j));
    }
    printf("%d\n",ans);
    return 0;
}

 

以上是关于codevs 3052 多米诺 二分图匹配的主要内容,如果未能解决你的问题,请参考以下文章

Codevs1922骑士共存问题(最小割,二分图最大匹配)

矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena

codeforces 1269D. Domino for Young (二分图证明/结论题)

CODEVS1922 骑士共存问题

互斥的数 (Codevs No.1553)

CODEVS1022 覆盖