POJ2466 棋盘覆盖

一张(n*m)的棋盘,有(k)个点不能被覆盖,问其余点能不能被(1*2)的小矩形完全覆盖,多测

这题先输入(m)是什么鬼啊!!!

其实是一个比较裸的二分图判定,把(k)个点挖去然后将剩余棋盘黑白染色,求二分图最大匹配数,若最大匹配数(+k==n*m)输出(YES)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace red{
#define int long long
#define mid ((l+r)>>1)
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	}
	typedef pair<int,int> p;
	const int N=50;
	int n,m,k,ret;
	int g[N][N];
	p f[N][N];
	bool vis[N][N];
	int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
	inline void dfs(int x,int y,int col)
	{
		g[x][y]=col;
		for(int i=0;i<4;++i)
		{
			int tx=x+dx[i],ty=y+dy[i];
			if(tx<1||tx>n||ty<1||ty>m) continue;
			if(!g[tx][ty]) dfs(tx,ty,col^1);
		}
	}
	inline bool find(int x,int y)
	{
		for(int i=0;i<4;++i)
		{
			int tx=x+dx[i],ty=y+dy[i];
			if(g[tx][ty]==(g[x][y]^1))
			{
				if(!vis[tx][ty])
				{
					vis[tx][ty]=1;
					if((f[tx][ty].first==0&&f[tx][ty].second==0)||find(f[tx][ty].first,f[tx][ty].second))
					{
						f[tx][ty]=p(x,y);
						return 1;
					}
				}
			}
		}
		return 0;
	}
	inline void main()
	{
		while(scanf("%lld%lld%lld",&m,&n,&k)==3)
		{
			memset(g,0,sizeof(g));
			memset(f,0,sizeof(f));
			ret=0;
			for(int x,y,i=1;i<=k;++i)
			{
				x=read(),y=read();
				g[x][y]=99;
			}
			for(int i=1;i<=n;++i)
			{
				for(int j=1;j<=m;++j)
				{
					if(!g[i][j]) dfs(i,j,2);
				}
			}
			for(int i=1;i<=n;++i)
			{
				for(int j=1;j<=m;++j)
				{
					if(g[i][j]==2)
					{
						memset(vis,0,sizeof(vis));
						if(find(i,j)) ++ret;
					}
				}
			}
			puts(ret*2+k==n*m?"YES":"NO");
		}
	}
}
signed main()
{
	red::main();
return 0;
}
原文地址:https://www.cnblogs.com/knife-rose/p/12082257.html