首页 > 代码库 > codevs 3052 多米诺 二分图匹配

codevs 3052 多米诺 二分图匹配

/*codevs 3052 二分图匹配 把矩阵分两批 黑和白 且黑白不相交 这就构成了二分图的两部分 然后求最大匹配*/#include<cstdio>#include<cstring>#define maxn 5010using 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 多米诺 二分图匹配