题目链接:http://poj.org/problem?id=2446
Description
Input
Output
Sample Input
4 3 2 2 1 3 3
Sample Output
YES
Hint
Source
PS:
把每个空格子当成一个点。
然后对于每个格子如果可以往上、下、左、右去找可以建立的边。
然后求最大匹配,如果最大匹配数刚好等于空格子数,输出YES,否则NO。
代码如下:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; int LN , RN; #define MAXN 2000 int n,m; int g[MAXN][MAXN], linker[MAXN]; bool used[MAXN]; int dfs(int L)//从左边开始找增广路径 { int R; for(R = 0 ; R < RN ; R++ ) { if(g[L][R]!=0 && !used[R]) { //找增广路,反向 used[R]=true; if(linker[R] == -1 || dfs(linker[R])) { linker[R]=L; return 1; } } } return 0;//这个不要忘了,经常忘记这句 } int hungary() { int res = 0 ; int L; memset(linker,-1,sizeof(linker)); for( L = 0 ; L < LN ; L++ ) { memset(used,0,sizeof(used)); if(dfs(L) != 0) res++; } return res; } int main() { int k,i,j,res,s,m,n,x,y; int num[70][70],graph[70][70]; while(~scanf("%d%d%d",&n,&m,&k)) { memset(g,0,sizeof(g)); memset(num,0,sizeof(num)); for(i = 1 ; i <= k ; i++ ) { scanf("%d%d",&x,&y); x--; y--; graph[y][x] = 1; } int ans=0; for(i = 0 ; i < n ; i++ ) { for(j = 0 ; j < m ; j++ ) { if(graph[i][j]==0) num[i][j]=ans++; } } LN = RN = ans; for(i = 0 ; i < n ; i++ ) { for( j = 0 ; j < m ; j++ ) { if(graph[i][j]==0) { int u = num[i][j]; if(i>0 && graph[i-1][j]==0) g[u][num[i-1][j]]=1; if(j>0 && graph[i][j-1]==0) g[u][num[i][j-1]]=1; if(i < n-1 && graph[i+1][j]==0) g[u][num[i+1][j]]=1; if(j < m-1 && graph[i][j+1]==0) g[u][num[i][j+1]]=1; } } } res = hungary(); if(res == ans) printf("YES\n"); else printf("NO\n"); } return 0 ; }