Chessboard(二分图完备匹配)

wa找不到原因,却是In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column。

关键在于建立图的过程,本题是典型的黑白染色法建立图形,

#include <iostream>

#include <cstring>

#include <cstdio>

using namespace std;

const int MAXN = 35*35;

int vN, uN;

bool g[MAXN][MAXN];

bool clr[MAXN][MAXN];

int xM[MAXN], yM[MAXN];

bool chk[MAXN];

int dx[] = {-1,0, 1, 0};

int dy[] = {0, 1, 0, -1};



bool searchPath(int u)

{

	int v;

	for(v = 0; v < vN; v++)

		if(g[u][v] && !chk[v])

		{

			chk[v] = true;

			if(yM[v] == -1 || searchPath(yM[v])) 

			{

				yM[v] = u;

				xM[u] = v;

				return true;

			}

		}

		return false;

}



int maxMatch()

{

	int u, ret = 0;

	memset(xM, -1, sizeof(xM));

	memset(yM, -1, sizeof(yM));

	for(u = 0; u < uN; u++)

		if(xM[u] == -1)

		{

			memset(chk,  false, sizeof(chk));

			if(searchPath(u))ret++;

		}

		return ret;

}

bool check(int x, int y, int m, int n)

{

	return x>=0 && x < m && y>=0 && y<n;

}

int main()

{

	int m,n,k,a,b;

	clr[0][0] = 1;

	int i,j;

	//给每一个部分染色 

	for(i =1; i < MAXN; i++)clr[0][i] = !clr[0][i-1];

	for(i = 1; i < MAXN; i++)

		for(j = 0; j < MAXN; j++)

			clr[i][j]= !clr[i-1][j];

	//end 染色	

		memset(g, 0, sizeof(g));

		scanf("%d%d%d",&m, &n, &k);

		int num[35][35];

		memset(num, 0, sizeof(num));

		

		//标记坏点,将a,b转换为数组下标 

		while(k--)

		{

			scanf("%d%d", &a, &b);

			a--;

			b--;

			num[b][a] = -1;

		}

		

		//统计出二分图矩阵的大小uN*vN 

		int cnt = 0;

		uN = vN = 0;

		for(i = 0; i < m; i++)

			for(j = 0; j < n; j++)

			{

				if(num[i][j] != -1)

				{

					if(clr[i][j]){num[i][j] = uN++;}

					else {num[i][j] = vN++;}

				}

			}

			

			

			if(uN != vN)

			{

				puts("NO");

			}

			else 

			{//建二分图,找相互连接的边 

				int ni,nj;

				for(i = 0; i < m; i++)

					for(j = 0; j < n; j++)

						if(num[i][j]!=-1 && clr[i][j])

						{

							for(k = 0; k < 4; k++)

							{

								ni = i + dx[k];

								nj = j + dy[k];

								if(check(ni,nj, m,n) && num[ni][nj]!=-1 )

								{

									g[num[i][j]][num[ni][nj]] = 1;

								}

							}

						}

						

				//如果可以完备匹配则成功,否则不成功		

				if(maxMatch() == vN)puts("YES");

				else puts("NO");

			}

			

	system("pause");

	return 0;

}

  

  

 

你可能感兴趣的:(二分图)