Description
Input
Output
Sample Input
4 3 2 2 1 3 3
Sample Output
YES
Hint
这题太坑,坐标输进来是列,行的,开始没注意错了很久,其他没什么难的,只要相邻且不是洞就连边。
然后求最大匹配,如果最大匹配等于剩余格子数量,就是YES,否则是NO
#include<stdio.h> #include<string.h> const int maxn=1605; struct node { int to; int next; }edge[4*maxn]; int head[maxn]; int mark[maxn]; bool used[maxn]; bool mat[55][55]; int cnt[55][55]; int tot; int n,m; int index; void addedge(int from,int to) { edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot++; } bool dfs(int x) { for (int i=head[x];i!=-1;i=edge[i].next) { if (!used[edge[i].to]) { used[edge[i].to]=1; if (mark[edge[i].to]==-1 || dfs(mark[edge[i].to])) { mark[edge[i].to]=x; return true; } } } return false; } int hungary() { memset(mark,-1,sizeof(mark)); int ans=0; for (int i=0;i<index;i++) { memset(used,0,sizeof(used)); if (dfs(i)) ans++; } return ans; } int main() { int k; while (~scanf("%d%d%d",&n,&m,&k)) { memset(head,-1,sizeof(head)); memset(mat,false,sizeof(mat)); tot=0; int x,y; for (int i=0;i<k;i++) { scanf("%d%d",&x,&y); x--; y--; mat[y][x]=true; } index=0; for (int i=0;i<n;i++) for (int j=0;j<m;j++) if (!mat[i][j]) cnt[i][j]=index++; for (int i=0;i<n;i++) for (int j=0;j<m;j++) { if (!mat[i][j]) { if (i>0 && !mat[i-1][j]) addedge(cnt[i][j],cnt[i-1][j]); if (i<n-1 && !mat[i+1][j]) addedge(cnt[i][j],cnt[i+1][j]); if (j>0 && !mat[i][j-1]) addedge(cnt[i][j],cnt[i][j-1]); if (j<m-1 && !mat[i][j+1]) addedge(cnt[i][j],cnt[i][j+1]); } } int res=hungary(); if (res==index) printf("YES\n"); else printf("NO\n"); } return 0; }