URAL 1229贴地砖 . 二分图匹配

来源:互联网 发布:js数组是否包含对象 编辑:程序博客网 时间:2024/04/28 15:54



铺地砖的时候要铺两层才能牢固??

给出了第一层
现在让铺第二层
第二层的地砖要跟第一层的完全错开 。
这是题意


用黑格子去跟白格子二分匹配
匹配成功就连一条线( X[i][j]=i   Y[i][j]=j  ) 
完成后 再根据给每个白格子和它的前导 赋值

输出


#include<iostream>#include<cstdio>#include<cstring>using namespace std;int MP[105][105],M,N,mp[105][105],X[105][105],Y[105][105];int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}};bool mark[105][105];bool find(int x,int y){int i,j,k,a,b;for(k=0;k<4;k++){a=x+dir[k][0];b=y+dir[k][1];if(a>0&&a<=M&&b>0&&b<=N&&mp[a][b]!=mp[x][y]&&!mark[a][b]){mark[a][b]=1;//printf("%d %d\n",a,b);if((!X[a][b]&&!Y[a][b])||find(X[a][b],Y[a][b]))//{X[a][b]=x;Y[a][b]=y;return 1;}}}return 0;}bool hungry(){int i,j;for(i=1;i<=M;i++)for(j=1;j<=N;j++)if((i&1)==(j&1)){memset(mark,0,sizeof(mark));if(!find(i,j))return 0;}return 1;}int main(){int i,j,k;while(scanf("%d%d",&M,&N)!=EOF){for(i=1;i<=M;i++)for(j=1;j<=N;j++)scanf("%d",&mp[i][j]);    memset(X,0,sizeof(X));memset(Y,0,sizeof(Y));if(!hungry()){printf("-1\n");continue;}k=1;for(i=1;i<=M;i++)for(j=1;j<=N;j++)if(!((i&1)==(j&1))){//printf("%d %d     %d %d\n",i,j,X[i][j],Y[i][j]);MP[i][j]=k;MP[X[i][j]][Y[i][j]]=k++;}//printf("%d!!!!\n",k);for(i=1;i<=M;i++){printf("%d",MP[i][1]);for(j=2;j<=N;j++)printf(" %d",MP[i][j]);printf("\n");}//printf("!%d!\n",MP[1][3]);}return 0;}