POJ 2446 最大匹配算法

Chessboard
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 6719 Accepted: 2103

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 2
2 1
3 3

Sample Output

YES

Hint


A possible solution for the sample input.

Source

POJ Monthly,charlescpp
算法的思想想好之后一直在思考实现,因为是第一次写这个,所以实现了很久终于把他敲出来了
不过代码很冗长,而且我自己分析了一下算法的复杂度,也不是很高明,所以还需要进一步的训练!!

Source Code

Problem: 2446 User: bingshen
Memory: 2364K Time: 297MS
Language: C++ Result: Accepted
  • Source Code
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    
    using namespace std;
    
    int map[33][33];
    bool flag[33][33];
    bool e[1500][1500];
    int lx[1500];
    int ly[1500];
    int link[2000];
    bool used[2000];
    int n,m,num2;
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    
    void init()
    {
    	memset(lx,0,sizeof(lx));
    	memset(ly,0,sizeof(ly));
    	memset(map,0,sizeof(map));
    	memset(flag,0,sizeof(flag));
    	memset(link,-1,sizeof(link));
    	memset(e,0,sizeof(e));
    }
    /*
    bool judge1(int x,int y)
    {
    	if(x>=1&&x<=n&&y>=1&&y<=m)
    		return true;
    	else
    		return false;
    }
    
    bool judge2(int x,int y)
    {
    	int u=x&1;
    	int v=y&1;
    	if(u!=v)
    		return true;
    	else
    		return false;
    }
    */
    bool dfs(int v)
    {
    	int i;
    	for(i=0;i<num2;i++)
    	{
    		if(e[v][ly[i]]&&!used[ly[i]])
    		{
    			used[ly[i]]=true;
    			if(link[ly[i]]==-1||dfs(link[ly[i]]))
    			{
    				link[ly[i]]=v;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    int main()
    {
    	int i,j,k,num0;
    	int x1,x2,y1,y2;
    	int x,y;
    	init();
    	num0=0;
    	scanf("%d%d%d",&n,&m,&k);
    	for(i=0;i<k;i++)
    	{
    		scanf("%d%d",&y,&x);
    		flag[x][y]=true;
    		num0++;
    	}
    	int num=1;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		{
    			map[i][j]=num;
    			num++;
    		}
    	int num1=0;
    	num2=0;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		{
    			if(((i+j)%2==0)&&!flag[i][j])
    				lx[num1++]=map[i][j];
    			else if(((i+j)%2==1)&&!flag[i][j])
    				ly[num2++]=map[i][j];
    		}
    	for(i=0;i<num1;i++)
    	{
    		x1=lx[i]/m;
    		y1=lx[i]%m;
    		if(y1==0)
    			y1=m;
    		else
    			x1++;
    //		printf("{/n");
    //		printf("(%d %d) %d/n",x1,y1,lx[i]);
    		for(j=0;j<num2;j++)
    		{
    			x2=ly[j]/m;
    			y2=ly[j]%m;
    			if(y2==0)
    				y2=m;
    			else
    				x2++;
    			int dis=abs(x1-x2)+abs(y1-y2);
    			if(dis==1)
    			{
    				e[lx[i]][ly[j]]=true;
    				e[ly[j]][lx[i]]=true;
    //				printf("(%d %d) %d/n",x2,y2,ly[j]);
    			}
    		}
    //		printf("}/n");
    	}
    //	for(i=0;i<num1;i++)
    //		printf("%d ",lx[i]);
    //	printf("/n");
    //	for(i=0;i<num2;i++)
    //		printf("%d ",ly[i]);
    //	printf("/n");
    	int ans=0;
    	for(i=0;i<num1;i++)
    	{
    		memset(used,0,sizeof(used));
    		if(dfs(lx[i]))
    			ans++;
    	}
    //	cout<<ans<<endl;
    	if(ans*2==(n*m-num0))
    		printf("YES/n");
    	else
    		printf("NO/n");
    	return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值