一张(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;
}