URAL 1229贴地砖 . 二分图婚配

URAL 1229贴地砖 . 二分图匹配

URAL 1229贴地砖 . 二分图婚配

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

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

.
.
.
.
中间过渡自己想叭
.
.
..
.
.

用黑格子去跟白格子二分匹配
匹配成功就连一条线( 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;
}


1楼dellaserss昨天 14:02
???