POJ - 2446 Chessboard (二分图匹配)

5人阅读 评论(0) 收藏 举报

题目链接:点击打开链接

题意:一个棋盘,n*m的大小,棋盘上有一些窟窿,让你往棋盘上放1*2的长方形。横着放,竖着放都可以,但是窟窿的地方不能放,只要你能填满棋盘就输出YES,填不满就输出NO。

题解:最开始=-=看到alice和bob,就以为是博弈论,博了半天没博出来,然后看到1*2的方格就又想到了状压DP,又压了半天=-=。然后放弃了。

搜搜题解才发现,是二分图匹配问题。(惊喜的一比)

我们先给给个棋盘从上到下,从左到右依次标号。

如4*4的图如下

(0,0) (0,1)(0,2)(0,3)

(1,0) (1,1)(1,2)(1,3)

(2,0) (2,1)(2,2)(2,3)

(3,0) (3,1)(3,2)(3,3)

我们观察会发现,如果一个格子的行号和列号加起来为奇数,那与它相邻的格子的行号和列号加起来一定是偶数,如果一个格子的行号和列号加起来为偶数,那与它相邻的格子的行号和列号加起来一定是奇数。这样,我们就可以把这张棋盘分为奇数集合和偶数集合。加边的时候,我们只需要加它上面或左面就可以了。(精髓所在)

然后建好图跑一遍二分图算法就行了。

博主用的是匈牙利算法,博主不打算讲。因为博主是感性的认知,没有理性的论证。所以推荐一个博客:https://blog.csdn.net/dark_scope/article/details/8880547

这个博客通俗易懂。

上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M = 33 * 33, N = M * M; 
int Head[M], top;
int match[M];
bool use[M],map[M][M];
int m, n, k;
struct node {
	int v;
	int next;
}edge[N];
void add(int u, int v) //奇 + 偶
{
	edge[top].v = v;
	edge[top].next = Head[u];
	Head[u] = top++;
}
bool  find(int u){
	int temp;
	for(int i = Head[u] ; i != - 1; i = edge[i].next){
		temp = edge[i].v;
		if(!use[temp]){
			use[temp] = true;
			if(match[temp] == -1 || find(match[temp])){
				match[temp] = u;
				return true;
			}
		}
	}
	return false;
}
int sum(int n){
	int sumall = 0;
	for(int i = 0 ; i < n ; i ++){
		memset(use,0,sizeof(use));
		if(find(i))
			sumall++;
	}
	return sumall;
}

int main()
{
	int x, y;
	while(scanf("%d%d%d", &m, &n, &k) != EOF)
	{
		if((m * n - k) & 1)
		{
			printf("NO\n");
			continue;
		}
		top = 0;
		memset(Head, -1, sizeof(Head));
		memset(match, -1, sizeof(match));
		memset(map, true, sizeof(map));
		for(int i = 0; i < k; ++i)
		{
			scanf("%d%d", &y, &x); //先y后x
			map[x - 1][y - 1] = false;
		}
		for(int i = 0; i < m; ++i)
		{
			for(int j = 0; j < n; ++j)
			{
				if(map[i][j])
				{
					if(i - 1 >= 0 && map[i - 1][j]) //上
					{
						if((i + j) & 1)
							add(i * n + j, (i - 1) * n + j);
						else
							add((i - 1) * n + j, i * n + j);
					}
					if(j - 1 >= 0 && map[i][j - 1]) //左
					{
						if((i + j) & 1)
							add(i * n + j, i * n + (j - 1));
						else
							add( i * n +(j - 1) , i * n + j);
					}
				}
			}
		}
		for(int i = 0 ; i < n * m ; i ++){
			for(int k = Head[i] ; k != -1 ; k = edge[k].next)
				cout << i << " " << edge[i].v << endl;
		} 
		printf("%s\n", sum(m * n) == ((m * n - k) / 2) ? "YES" : "NO");
	}
	return 0;
}

查看评论

poj 2446 Chessboard(二分图最大匹配)

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16624   Ac...
  • acm_cxq
  • acm_cxq
  • 2016年07月27日 09:57
  • 211

POJ 2446 Chessboard(二分图-网格图构图)

http://poj.org/problem?id=2446 这道题,十分的妙啊。我一开始死活想不出到底怎么做,这竟然是二分图???我往这方面想也没有结果。后来在网上看到了二分图常用的建图技巧,我看...
  • llzhh
  • llzhh
  • 2017年05月02日 17:43
  • 253

POJ-2446 Chessboard

题目链接:http://poj.org/problem?id=2446 题目大意: 给你一个m*n的棋盘,其中有k个小洞,现在给你1*2的纸片,如果能恰好覆盖没有洞的全部格子,而且每个格子不能被覆...
  • niushuai666
  • niushuai666
  • 2011年12月01日 15:56
  • 3076

poj_2446 Chessboard匈牙利算法

思路:
  • yeruby
  • yeruby
  • 2014年09月26日 10:36
  • 676

POJ2446 Chessboard(二分图)

题意: 一个n*m的棋盘上有t个坑,要求用1*2的纸条完全覆盖这个棋盘,纸条不能盖上坑。 要点: 这题是二分图,就是求二分图的最大匹配,看是否与棋盘格子数-坑数相等。但是具体的集合很难想,看了网...
  • SeasonJoe
  • SeasonJoe
  • 2016年06月05日 10:06
  • 233

POJ 2446 Chessboard(二分图匹配)

题目大意: 首先输入m,n,k,表示一个m*n的格子,ranho
  • u011643500
  • u011643500
  • 2014年04月09日 10:51
  • 397

Chessboard - POJ 2446 二分图匹配

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14001   Ac...
  • u014733623
  • u014733623
  • 2014年10月28日 18:06
  • 400

POJ 2446 Chessboard二分图匹配

Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M ...
  • Dante__Alighieri
  • Dante__Alighieri
  • 2017年05月24日 21:05
  • 209

POJ 2446 Chessboard (二分图匹配)

POJ 2446 Chessboard (二分图匹配)
  • u012860063
  • u012860063
  • 2014年02月26日 22:32
  • 1034

二分图之poj2446

题目:poj2446 题意:给出一个m*n的矩阵,其中有的地方有坑,然后用1*2的纸片去覆盖图,纸片不能重复,能够把出了坑的地方其他全部覆盖的话输出YES,否则NO 分析:有一道二...
  • y990041769
  • y990041769
  • 2014年07月16日 11:28
  • 2465
    个人资料
    持之以恒
    等级:
    访问量: 7152
    积分: 1496
    排名: 3万+
    文章分类
    最新评论