Chessboard(二分图匹配)

Chessboard

Time Limit: 2000MSMemory Limit: 65536K

Total Submissions: 14479Accepted: 4501

Description

Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2 to cover the board. However, she thinks it too easy to bob, so she makes some holes on the board (as shown in the figure below).

We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below:1. Any normal grid should be covered with exactly one card.2. One card should cover exactly 2 normal adjacent grids.Some examples are given in the figures below:

A VALID solution.

An invalid solution, because the hole of red color is covered with a card.

An invalid solution, because there exists a grid, which is not covered.Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.

Input

There are 3 integers in the first line: m, n, k (0 < m, n <= 32, 0 <= K < m * n), the number of rows, column and holes. In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column.

Output

If the board can be covered, output "YES". Otherwise, output "NO".

Sample Input

4 3 22 13 3

Sample Output

YES

Hint

A possible solution for the sample input.

题意:给出一个矩形N*M棋盘,有K个格子是空洞,然后用2*1的矩形,对所有非空洞的格子进行覆盖,问能否完全覆盖。

分析:二分图匹配问题。关键问题是如何建图,我们可以把每两个相邻的非空格子用一条边连接起来,这样的话相当于这两个格子处于分别处于两个集合当中,这样的话两个相邻的格子就不会处于同一个集合当中。然后这样子连边就构成了一个二分图了。然后求出最大匹配数。如果匹配数 + k = N*M,输出“YES”。

题目链接:?id=2446

代码清单:

#include<map>#include<queue>#include<cmath>#include<stack>#include<ctime>#include<cctype>#include<string>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 32 + 5;const int maxv = 2000 + 5;int m,n,k;int x,y,cnt;int match[maxv];bool vis[maxv];int num[maxn][maxn];bool hole[maxn][maxn];bool graph[maxv][maxv];bool dfs(int u){//匈牙利算法for(int v=1;v<=cnt;v++){if(!vis[v]&&graph[u][v]){vis[v]=true;if(match[v]==-1 || dfs(match[v])){match[v]=u;return true;}}}return false;}bool ok(){int ans=0;for(int i=1;i<=cnt;i++){memset(vis,false,sizeof(vis));if(dfs(i)) ans++;}if(ans==cnt) return true;return false;}int main(){scanf("%d%d%d",&m,&n,&k);memset(match,-1,sizeof(match));memset(hole,false,sizeof(hole));memset(graph,false,sizeof(graph));for(int i=0;i<k;i++){scanf("%d%d",&x,&y);hole[y-1][x-1]=true;}if((n*m-k)&1) printf("NO\n"); //奇偶性剪枝else{cnt=0;for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(!hole[i][j])num[i][j]=++cnt;}}//建立二分图 for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(!hole[i][j]){if(i-1>=0&&!hole[i-1][j]) graph[num[i][j]][num[i-1][j]]=true;if(i+1<m&&!hole[i+1][j]) graph[num[i][j]][num[i+1][j]]=true;if(j-1>=0&&!hole[i][j-1]) graph[num[i][j]][num[i][j-1]]=true;if(j+1<n&&!hole[i][j+1]) graph[num[i][j]][num[i][j+1]]=true;}}} if(ok()) printf("YES\n");else printf("NO\n");}return 0;}

,就是对虚怀若谷谦虚谨慎八个字真正理解的人,

Chessboard(二分图匹配)

相关文章:

你感兴趣的文章:

标签云: