二分图练习
棋盘。
相邻两点的匹配。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
const int MAX=33;
bool map[MAX][MAX];
int match[MAX*MAX+MAX+1];
int visit[MAX*MAX+MAX+1];
int Left[MAX*MAX];
int n,m,k;
int x,y;
int chx[]={-1,0,1,0};
int chy[]={0,1,0,-1};
int cnt;
bool in_map(int nk)
{
int nx=nk/MAX;
int ny=nk%MAX;
if(nx<=n&&nx>=1&&ny<=m&&ny>=1)
return true;
return false;
}
bool dfs(int k)
{
for(int i=0;i<4;i++)
{
int nx=k/MAX+chx[i];
int ny=k%MAX+chy[i];
int nk=nx*MAX+ny;
if(in_map(nk)&&!map[nx][ny]&&!visit[nk])
{
visit[nk]=true;
if(match[nk]==-1||dfs(match[nk]))
{
match[nk]=k;
return true;
}
}
}
return false;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
memset(match,-1,sizeof(match));
memset(map,0,sizeof(map));
if((m*n-k)%2==1)
{
printf("NO\n");
continue;
}
for(int i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
map[y][x]=true;
}
cnt=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if((i+j)%2==0&&!map[i][j])
Left[cnt++]=i*MAX+j;
}
}
int ans=0;
for(int i=1;i<cnt;i++)
{
memset(visit,0,sizeof(visit));
if(dfs(Left[i])) ans++;
}
if(ans==(cnt-1))
printf("YES\n");
else printf("NO\n");
}
}