poj2289多重二分匹配
来源:互联网 发布:sql 查询数据库大小 编辑:程序博客网 时间:2024/05/16 12:08
poj2289多重二分匹配
- 题目链接:http://poj.org/problem?id=2289
题目部分
题意:
题目说一个人要给电话簿进行分组,每个人可以分到特定的组(一个人只能进一个组,但供选择的组有多个)。要你计算分到人数最多的那个组,最小有几个人
输入数据
多组测试数据,每组测试数据先输入2个数,第一个数是人数n,第二个数是组数m,如果这两个数输入的是0 0表示程序结束。
接下来n行会结束人的信息
名字 可以进入的组(这里没有说明有几组所有输入的时候要做好处理)
这里组是从0开始计算的。
输出数据
最多人数的那个组中最小人数。
样例解析:
3 2
John 0 1
Rose 1
Mary 1
5 4
ACM 1 2 3
ICPC 0 1
Asian 0 2 3
Regional 1 2
ShangHai 0 2
0 0
第一组数据:
有3个人,2个组
John 可以进入 0、1组
Rose 可以进入1组
Mary 可以进入1组
第二组数据:
ACM 可以进入1、2、3组
ICPC 可以进入0、1组
Asian 可以进入0、2、3组
Regional 可以进入1、2组
ShangHai 可以进入0、2组
第一组输出:
可以3个人都进1组,这样最大人数的组的人数是3
可以John进0组,剩下2个人进1组,这样最大人数的组人数是2
所以输出结果是2。(就写一组了,( ⊙ o ⊙ )懒了)
思路部分
要看二分匹配的可以看这个博客:
http://blog.csdn.net/dark_scope/article/details/8880547
(前面一篇博客就推过)
这题跟二分匹配的差别就在于右边可以连接多个左边,所以把二分匹配中保存右边的连接数组改成二维数组就可以了,你可以另外拿一个数组存放了几个数,我这边是用这个二维数组的connect[i][0]来存放第i行存了几个数。
这样要找最小我们就可以遍历所有可能,也就是最大的组的人数可能,从1到n(所有人都进到一个组),这里用二分法搜索加速
像第一组测试数据,假设最少3人进行二分多重匹配,所有人都匹配上那么这种情况是可以的,我们就缩小范围。
2个人是最少的这样所有人还是都匹配上了,继续缩小,1个人最少,这样有人没有匹配上,那么最少的人数就是2了。
代码部分
#define _CRT_SECURE_NO_DEPRECATE#include<iostream>#include<cstring>#include<algorithm>#include<fstream>#include<math.h>#include<algorithm>#include<stack>#include<queue>using namespace std;//fstream fin("1.txt");//streambuf *buf = cin.rdbuf(fin.rdbuf());//用于重定项输入改成,把cin当成fin//FILE *buf = freopen("1.txt", "a+", stdin);//用于重定项文件输入,scanf也能用(这里代码的第一行必须加上才能用这句话)const int inf = 1 << 29;const int MAXN = 1010;int n, m;int limit;int map[MAXN][MAXN];int connect[MAXN][MAXN];//每行的0保存这一行存放了几个数bool vis[MAXN];bool find(int p){ for (int i = 1; i <= m; i++) { if (map[p][i] && !vis[i]) { vis[i] = true; if (connect[i][0] < limit) { connect[i][0]++; connect[i][connect[i][0]] = p; return true; } for (int j = 1; j <= connect[i][0]; j++) { if (find(connect[i][j])) { connect[i][j] = p; return true; } } } } return false;}bool judge(){ memset(connect, 0, sizeof(connect)); for (int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); if (!find(i))//如果返回false,就说明找不到合适的匹配,那么这个Limit就不行直接退出<因为每个人都有被分配到组里面 return false; } return true;}int main(){ char str[20]; int a; int left, right; while (cin >> n >> m && (n + m)) { memset(map, 0, sizeof(map)); for (int i = 1; i <= n; i++) { scanf_s("%s", str, 20); while (true) { scanf_s("%d", &a); map[i][a + 1] = 1; if (getchar() == '\n') break; } } left = 0; right = n + 1; int result; while (left <= right) { limit = (left + right) >> 1; if (judge()) { result = limit; right = limit - 1; } else left = limit + 1; } cout << result << endl; } return 0;}
- poj2289多重二分匹配
- 二分图多重匹配--poj2289
- 【POJ2289】【多重匹配】【二分】【模板】
- poj2289(二分多重匹配)
- POJ2289 Jamie's Contact Groups(二分图多重匹配+二分)
- POJ2289 Jamie's Contact Groups 二分图多重匹配
- POJ2289-Jamie's Contact Groups(二分图多重匹配)
- POJ2289 Jamie's Contact Groups(二分图多重匹配)
- poj2289--Jamie's Contact Groups(二分多重匹配)
- poj2289 Jamie's Contact Groups(二部图多重匹配)
- POJ2289 Jamie's Contact Groups 二分+最大流匹配
- 二分多重匹配模板
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 爱奇艺2016在线笔试
- 【UML】宏观结构与概述
- 强制声明泛型的实际类型
- Codevs P1066 引水入城 2010年NOIP全国联赛提高组
- POJ 1743 Musical Theme (后缀数组)
- poj2289多重二分匹配
- HDU 5532 Almost Sorted Array (2015ACM/ICPC长春&&LIS)
- 软件质量模型
- 逻辑斯蒂回归 Logstic Regression in Python
- 开源框架spring AOP的深刻理解
- form表单被自动提交
- 【设计模式】Filter-Chain 的应用
- 关联选择器和组合选择器,伪元素选择器
- Modern OpenGL ES: ndk编程——画一个三角形之Shader工程