思路:和之前的建立网络战的题目类似,就是通过当前的合要求的点开始向四周寻找,若四周有合格的便将他们建立关系。注意其中的边界处理
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#define inf 0x3f3f3f3f
using namespace std;
int Map[2000][2000],cropath[6000],id[2000][2000],head[2000];
bool use[6000],vis[2000][2000];
int n,m,z;
struct node
{
int to,next;
} q[10000];
int cnt;
void creat(int a,int b)
{
q[z].to=b;
q[z].next=head[a];
head[a]=z++;
}
int DFS(int v)
{
int i,k;
for(i=head[v]; i!=-1; i=q[i].next)
{
k=q[i].to;//看的是当前的顶点是否被用
if(!use[k])
{
use[k]=true;
if(cropath[k]==-1||DFS(cropath[k]))
{
cropath[k]=v;
return 1;
}
}
}
return 0;
}
int main()
{
int a,b,n,m,i,j,k;
while(~scanf("%d%d%d",&m,&n,&k))
{
z=0;
memset(head,-1,sizeof(head));
memset(cropath,-1,sizeof(cropath));
memset(vis,false,sizeof(vis));
for(i=0; i<k; i++)
{
scanf("%d%d",&a,&b);
vis[b][a]=true;
}
if(((n*m)-k)&1)
{
printf("NO\n");
continue;
}
cnt=0;
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
if(!vis[i][j])//统计有多少正常的格子
id[i][j]=cnt++;
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
if(!vis[i][j])
{
if(i-1>0&&!vis[i-1][j])//注意边界
creat(id[i][j],id[i-1][j]);
if(j-1>0&&!vis[i][j-1])
creat(id[i][j],id[i][j-1]);
if(i+1<=m&&!vis[i+1][j])
creat(id[i][j],id[i+1][j]);
if(j+1<=n&&!vis[i][j+1])
creat(id[i][j],id[i][j+1]);
}
int ans=0;
for(i=0; i<cnt; i++)
{
memset(use,false,sizeof(use));
if(DFS(i))
ans++;
}
//cout<<ans<<endl;
if(ans==cnt)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}