POJ2446 Chessboard(二分图)
2016-06-05 10:06
519 查看
题意:
一个n*m的棋盘上有t个坑,要求用1*2的纸条完全覆盖这个棋盘,纸条不能盖上坑。
要点:
这题是二分图,就是求二分图的最大匹配,看是否与棋盘格子数-坑数相等。但是具体的集合很难想,看了网上题解,确实比较精妙。首先我们知道如果一个格子的行数+列数i+j是奇数,它相邻的格子的i+j必定为偶数,所以我们只要用i+j为奇数的为一个集合,偶数为一个集合,求出最大匹配数即可。
一个n*m的棋盘上有t个坑,要求用1*2的纸条完全覆盖这个棋盘,纸条不能盖上坑。
要点:
这题是二分图,就是求二分图的最大匹配,看是否与棋盘格子数-坑数相等。但是具体的集合很难想,看了网上题解,确实比较精妙。首先我们知道如果一个格子的行数+列数i+j是奇数,它相邻的格子的i+j必定为偶数,所以我们只要用i+j为奇数的为一个集合,偶数为一个集合,求出最大匹配数即可。
15590489 | Seasonal | 2446 | Accepted | 940K | 219MS | C++ | 1508B | 2016-06-05 09:46:45 |
#include<stdio.h> #include<stdlib.h> #include<string.h> #define N 1500 bool map , used ; int girl ,path[50][50]; int n, m,t,odd,even; bool find(int x) { for (int i = 1; i < even; i++) { if (map[x][i] && used[i] == false) { used[i] = true; if (girl[i] == -1 || find(girl[i])) { girl[i] = x; return true; } } } return false; } void solve() { int ans = 0; memset(girl, -1, sizeof(girl)); for (int i = 1; i < odd; i++) { memset(used, false, sizeof(used)); if (find(i)) ans++; } if (ans * 2 == (m*n - t))//如果最大匹配数*2与总格子数相等说明成功 printf("YES\n"); else printf("NO\n"); } int main() { int i, j; while (~scanf("%d%d", &n, &m)) { memset(path, 0, sizeof(path)); memset(map, false, sizeof(path)); scanf("%d", &t); int y, x; for (i = 0; i < t; i++) { scanf("%d%d", &x, &y); path[y][x] = -1; //小心这里行列搞反 } odd = even = 1; for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) { if (path[i][j] != -1) { if ((i + j) % 2 == 1)//对应的奇数集合 path[i][j] = odd++;//进行标号 if ((i + j) % 2 == 0)//对应的偶数集合 path[i][j] = even++; } } for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) { if (path[i][j] != -1 && (i + j) % 2 == 1)//(i+j)为奇数说明它四周都是偶数 { if (path[i - 1][j] >= 1) map[path[i][j]][path[i - 1][j]] = true; if (path[i + 1][j] >= 1) map[path[i][j]][path[i + 1][j]] = true; if (path[i][j-1] >= 1) map[path[i][j]][path[i][j-1]] = true; if (path[i][j+1] >= 1) map[path[i][j]][path[i][j+1]] = true; } } solve(); } return 0; }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua和C语言的交互详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解