Chessboard POJ2446 wikioi 1022 wikioi 3052

来源:互联网 发布:js如何修改元素属性值 编辑:程序博客网 时间:2024/05/17 00:09
Chessboard
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 11075 Accepted: 3448

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

【注】可以参考http://blog.csdn.net/lyy289065406/article/details/6647040






我们以下面这个样例为例

2 3 11 1

就可以得到如下图


我们把它标上号,然后在可以放置的上面连边,如 2<->4 , 3<->5 , 5<->6 等


然后我们可以求出最大匹配,下图为其中一个最大匹配


所以最大匹配为4,而图中所给的方块有N*M-K个可以放置

4≠N*M-K,所以不可行


而题中所给样例求出的最大匹配为10=N*M-K,所以可行



PS:看网上一些大牛利用单调性建图的,很巧妙,佩服。。。。。


#define _TEST _TEST#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <cmath>#include <algorithm>using namespace std;//////////////////////////////////////////////////int n,m,_k;int map[101][101]={0};struct edge{    int v,next;}e[19801];int head[10001];int k=0;int pre[10001];bool vis[10001];int dx[]={0,1};int dy[]={1,0};//////////////////////////////////////////////////void adde(int u,int v){    e[k].v=v; e[k].next=head[u]; head[u]=k++;}bool search(int u){    for(int i=head[u];i!=-1;i=e[i].next)    {        int v=e[i].v;        if(vis[v]) continue;        vis[v]=1;        if(pre[v]==0||search(pre[v]))        {            pre[v]=u;            return 1;        }    }    return 0;}//////////////////////////////////////////////////void init(){     freopen("1022.in","r",stdin);     freopen("1022.out","w",stdout);}void readdata(){     memset(head,-1,sizeof(head));     scanf("%d%d%d",&n,&m,&_k);     int x,y;     for(int i=1;i<=_k;i++)     {         scanf("%d%d",&x,&y);         map[x][y]=1;     }     for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++) if(!map[i][j])     {         for(int k=0;k<2;k++)         {             x=i+dx[k],y=j+dy[k];             if(x<1||x>n||y<1||y>m) continue;             if(map[x][y]) continue;             adde((i-1)*m+j,(x-1)*m+y);             adde((x-1)*m+y,(i-1)*m+j);             //adde(x*n+y,i*n+j);         }     }}void work(){     //init     int ans=0;     //calculate     for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)     {          memset(vis,0,sizeof(vis));          if(search((i-1)*m+j)) ans++;     }     //output     printf("%d",ans>>1);}//////////////////////////////////////////////////int main(){     #ifndef _TEST     init();     #endif     readdata();     work();     #ifdef _TEST     for(;;);     #endif     return 0;}


0 0
原创粉丝点击