POJ-2446 Chessboard
2011-12-01 15:56
363 查看
题目链接:http://poj.org/problem?id=2446
题目大意:
给你一个m*n的棋盘,其中有k个小洞,现在给你1*2的纸片,如果能恰好覆盖没有洞的全部格子,而且每个格子不能被覆盖2次,一张纸也必须是1*2规模的,这样就输出YES。
解题思路:
这道题是搜二分图搜到的。但是竟然一点也看不出来哪里能用二分图最大匹配来做。只好去搜题解了。。。
思路是:
把这个棋盘看成一个类似国际象棋的棋盘,黑白相间的那种。任何2个相邻的格子肯定是不同颜色的(黑和白)。经过研究发现,如果一个格子的行号和列号加起来为奇数,那与它相邻的格子的行号和列号加起来一定是偶数,如果一个格子的行号和列号加起来为偶数,那与它相邻的格子的行号和列号加起来一定是奇数。
这样,我们就可以把这张棋盘分为奇数集合和偶数集合。加边的时候,我们只需要加它上面或左面就可以了。。
代码如下:
题目大意:
给你一个m*n的棋盘,其中有k个小洞,现在给你1*2的纸片,如果能恰好覆盖没有洞的全部格子,而且每个格子不能被覆盖2次,一张纸也必须是1*2规模的,这样就输出YES。
解题思路:
这道题是搜二分图搜到的。但是竟然一点也看不出来哪里能用二分图最大匹配来做。只好去搜题解了。。。
思路是:
把这个棋盘看成一个类似国际象棋的棋盘,黑白相间的那种。任何2个相邻的格子肯定是不同颜色的(黑和白)。经过研究发现,如果一个格子的行号和列号加起来为奇数,那与它相邻的格子的行号和列号加起来一定是偶数,如果一个格子的行号和列号加起来为偶数,那与它相邻的格子的行号和列号加起来一定是奇数。
这样,我们就可以把这张棋盘分为奇数集合和偶数集合。加边的时候,我们只需要加它上面或左面就可以了。。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int M = 33 * 33, N = M * M; int Head[M], Next , Key , top; int match[M]; bool use[M], map[M][M]; int m, n, k; void add(int u, int v) //奇 + 偶 { Key[top] = v; Next[top] = Head[u]; Head[u] = top++; } bool find(int u) { int temp; for(int i = Head[u]; i != -1; i = Next[i]) { temp = Key[i]; 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, false, 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); } } } } printf("%s\n", sum(m * n) == ((m * n - k) / 2) ? "YES" : "NO"); } return 0; }
相关文章推荐
- POJ 2446 Chessboard(奇偶建点法+最大匹配)
- POJ_2446 Chessboard
- POJ 2446 Chessboard(二分图匹配)
- [poj 2446]Chessboard
- poj 2446 Chessboard 二分图的最大匹配
- POJ 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard
- POJ2446--Chessboard
- poj 2446 Chessboard
- poj 2446 Chessboard(二分图最大匹配)
- poj 2446 Chessboard(经典二分匹配)
- POJ 2446 Chessboard(二分匹配-hungary)
- POJ 2446 Chessboard(匈牙利算法)
- POJ 2446 Chessboard(二分图匹配)
- POJ_2446_Chessboard
- POJ 2446 Chessboard (二分图匹配)
- POJ 2446 Chessboard (匈牙利算法)
- poj 2446(二分匹配) Chessboard
- poj 2446 Chessboard (二分匹配)
- POJ 2446 Chessboard(二分图匹配)