简单二分图匹配
#include<stdio.h>
#include<string.h>
#define con 1100
int m,n,p; //m=row,n=col
int map[con][con];
int cx[con],cy[con];
bool mk[con];
bool is[33][33];
int path(int u){
int i;
for(i=0;i<m*n;i++){
if(map[u][i] && mk[i]==0){
mk[i]=1;
if(cy[i]==0 || path(cy[i])){
cx[u]=i;
cy[i]=u;
return 1;
}
}
}
return 0;
}
int maxmatch(){
int i,j,u,v,sum=0;
memset(cx,0,sizeof(cx));
memset(cy,0,sizeof(cy));
for(i=0;i<m*n;i++){
if(cx[i]==0){
memset(mk,0,sizeof(mk));
sum+=path(i);
}
}
return sum;
}
bool isok(int u,int v){
if(u>=0 && v>=0 && u<m && v<n && !is[u][v])
return 1;
return 0;
}
int main(){
int i,j,u,v,t=1;
scanf("%d %d %d",&m,&n,&p);
memset(map,0,sizeof(map));
memset(is,0,sizeof(is));
for(i=1;i<=p;i++){
scanf("%d %d",&u,&v); //u is col,v is row
is[v-1][u-1]=1;
}
for(i=0;i<m;i++)
for(j=0;j<n;j++){
if(is[i][j])
continue;
if(isok(i+1,j))
map[i*n+j][(i+1)*n+j]=1;
if(isok(i,j+1))
map[i*n+j][i*n+j+1]=1;
if(isok(i,j-1))
map[i*n+j][i*n+j-1]=1;
if(isok(i-1,j))
map[i*n+j][(i-1)*n+j]=1;
}
if(maxmatch()==(m*n-p))
printf("YES\n");
else
printf("NO\n");
}