poj 2446 poj 1469 poj 1274 二分图最大匹配
来源:互联网 发布:sqlserver置疑的原因 编辑:程序博客网 时间:2024/05/24 02:38
poj 2446:
题意:
给一张m * n的图,其中挖掉一些点,然后用1*2的小纸片来覆盖这张图,问能否将这个图覆盖。
如下图:
解析:
将每个不为挖掉的点视为二分图的X点集,这个点的四个方向上的点视为Y点集,此时最大匹配数即为点的个数(想一想为什么)。
因为有重复匹配 1和2
2和1
这题用一个id数组来处理每个点的id,然后用匈牙利算法求最大匹配就ok了。
代码:
(邻接矩阵版)1552K 172MS
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 33 * 33;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dir[][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};bool maze[maxn][maxn];vector<int> g[maxn];bool vis[maxn];int fr[maxn];int m, n, k;int cnt;int id[maxn][maxn];bool match(int v){ for (int i = 0; i < g[v].size(); i++) { int u = g[v][i]; if (!vis[u]) { vis[u] = true; if (fr[u] == -1 || match(fr[u])) { fr[u] = v; return true; } } } return false;}int hungary(){ int ret = 0; memset(fr, -1, sizeof(fr)); for (int i = 1; i <= cnt; i++) { memset(vis, false, sizeof(vis)); if (match(i)) ret++; } return ret;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL while (~scanf("%d%d%d", &m, &n, &k)) { memset(maze, true, sizeof(maze)); for (int i = 0; i < k; i++) { int x, y; scanf("%d%d", &y, &x); maze[x][y] = false; } if ((m * n - k) % 2) { printf("NO\n"); } else { cnt = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (maze[i][j]) { id[i][j] = ++cnt; } } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (maze[i][j]) { for (int d = 0; d < 4; d++) { int ni = i + dir[d][0]; int nj = j + dir[d][1]; if (1 <= ni && ni <= m && 1 <= nj && nj <= n && maze[ni][nj]) { g[id[i][j]].push_back(id[ni][nj]); } } } } } //cout << hungary() <<endl; if (hungary() + k == m * n) { printf("YES\n"); } else { printf("NO\n"); } } } return 0;}
(邻接表) 1492K 94MS
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 33 * 33;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dir[][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};bool maze[maxn][maxn];bool vis[maxn];int fr[maxn];int m, n, k;int cnt;int id[maxn][maxn];struct edge{ int to, next;} e[maxn];int head[maxn];int index;void addedge(int u, int v){ e[index].to = v; e[index].next = head[u]; head[u] = index; index++;}bool match(int v){ for (int i = head[v]; i != -1; i = e[i].next) { int u = e[i].to; if (!vis[u]) { vis[u] = true; if (fr[u] == -1 || match(fr[u])) { fr[u] = v; return true; } } } return false;}int hungary(){ int ret = 0; memset(fr, -1, sizeof(fr)); for (int i = 1; i <= cnt; i++) { memset(vis, false, sizeof(vis)); if (match(i)) ret++; } return ret;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL while (~scanf("%d%d%d", &m, &n, &k)) { memset(maze, true, sizeof(maze)); for (int i = 0; i < k; i++) { int x, y; scanf("%d%d", &y, &x); maze[x][y] = false; } if ((m * n - k) % 2) { printf("NO\n"); } else { cnt = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (maze[i][j]) { id[i][j] = ++cnt; } } } memset(head, -1, sizeof(head)); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (maze[i][j]) { for (int d = 0; d < 4; d++) { int ni = i + dir[d][0]; int nj = j + dir[d][1]; if (1 <= ni && ni <= m && 1 <= nj && nj <= n && maze[ni][nj]) { addedge(id[i][j], id[ni][nj]); } } } } } //cout << hungary() <<endl; if (hungary() + k == m * n) { printf("YES\n"); } else { printf("NO\n"); } } } return 0;}
poj 1469:
题意:
给课程和喜欢这门课的学生。
问是否存在每个不同的学生喜欢不同的课。
解析:
最直接的二分图匹配。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 300 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);vector<int> g[maxn];int fr[maxn];bool vis[maxn];int p, n;bool match(int v){ for (int i = 0; i < g[v].size(); i++) { int u = g[v][i]; if (!vis[u]) { vis[u] = true; if (fr[u] == -1 || match(fr[u])) { fr[u] = v; return true; } } } return false;}int angary(){ int ret = 0; memset(fr, -1, sizeof(fr)); for (int i = 1; i <= p; i++) { memset(vis, false, sizeof(vis)); if (match(i)) { ret++; } } return ret;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int ncase; scanf("%d", &ncase); while (ncase--) { for (int i = 0; i < maxn; i++) g[i].clear(); scanf("%d%d", &p, &n); for (int i = 1; i <= p; i++) { int k; scanf("%d", &k); while (k--) { int x; scanf("%d", &x); g[i].push_back(x); } } // cout << angary() << endl; if (angary() == p) printf("YES\n"); else printf("NO\n"); } return 0;}
poj 1274
题意:
二分图最大匹配。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 200 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);vector<int> g[maxn];int fr[maxn];bool vis[maxn];int n, m;bool match(int v){ for (int i = 0; i < g[v].size(); i++) { int u = g[v][i]; if (!vis[u]) { vis[u] = true; if (fr[u] == -1 || match(fr[u])) { fr[u] = v; return true; } } } return false;}int hungary(){ int ret = 0; memset(fr, -1, sizeof(fr)); for (int i = 1; i <= n; i++) { memset(vis, false, sizeof(vis)); if (match(i)) { ret++; } } return ret;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL while (~scanf("%d%d", &n, &m)) { for (int i = 0; i <= n; i++) g[i].clear(); for (int i = 1; i <= n; i++) { int k; scanf("%d", &k); while (k--) { int x; scanf("%d", &x); g[i].push_back(x); } } printf("%d\n", hungary()); } return 0;}
0 0
- poj 2446 poj 1469 poj 1274 二分图最大匹配
- POJ 1274 / POJ 1469 / POJ 2239 二分图最大匹配
- POJ 2446 二分最大匹配
- poj 2446 二分图 最大匹配
- POJ 2446 Chessboard(二分图最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- poj--2446 Chessboard(二分图最大匹配)
- POJ 2446 Chessboard(二分图最大匹配)
- POJ 1469 二分图最大匹配
- poj 1469 二分图最大匹配
- POJ 1469二分图最大匹配
- POJ 1469 二分图最大匹配 COURSES
- POJ 1469 COURSES(二分图最大匹配)
- 【二分图|最大匹配】POJ-1469 COURSES
- poj 1469 COURSES 二分图最大匹配
- POJ 1469 COURSES(二分图最大匹配)
- POJ 1469 COURSES(最大二分图匹配)
- POJ-1469 COURSES(二分图最大匹配)
- HDU 4133 StrangeStandard 反素数
- CentOS中vsftp安装、配置、卸载
- 使用Maven进行测试
- 显式启动一个service组件
- 关于ios项目目录规范结构探讨
- poj 2446 poj 1469 poj 1274 二分图最大匹配
- java synchronized详解
- iOS 开发-理解Certificate、AppId和Provisioning Profile
- CSS -webkit-box的属性
- IOS NSArray & NSDictoray -持续更新
- hostapd交叉编译及测试脚本
- 64位操作系统,mysql ODBC 驱动程序和应用程序之间的体系结构不匹配
- Stackoverflow 精彩答案搬运之 Enum类型
- php之curl设置超时实例【转】