poj-2289.jamies contact groups(二分答案 + 二分多重匹配)

时间:2022-12-26 15:47:55

Jamie's Contact Groups

Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 9227   Accepted: 3180

Description

Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The contact list has become so long that it often takes a long time for her to browse through the whole list to find a friend's number. As Jamie's best friend and a programming genius, you suggest that she group the contact list and minimize the size of the largest group, so that it will be easier for her to search for a friend's number among the groups. Jamie takes your advice and gives you her entire contact list containing her friends' names, the number of groups she wishes to have and what groups every friend could belong to. Your task is to write a program that takes the list and organizes it into groups such that each friend appears in only one of those groups and the size of the largest group is minimized.

Input

There will be at most 20 test cases. Ease case starts with a line containing two integers N and M. where N is the length of the contact list and M is the number of groups. N lines then follow. Each line contains a friend's name and the groups the friend could belong to. You can assume N is no more than 1000 and M is no more than 500. The names will contain alphabet letters only and will be no longer than 15 characters. No two friends have the same name. The group label is an integer between 0 and M - 1. After the last test case, there is a single line `0 0' that terminates the input.

Output

For each test case, output a line containing a single integer, the size of the largest contact group.

Sample Input

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

Sample Output

2
2

Source

 
这题做了有好一会,他是在求匹配所有人之后匹配分组中最大值的最小值,虽然很明显是个二分,但是......我老感觉改一下匹配的代码就过了...而且最致命的是我自己试的答案都过了嘤嘤嘤,我的第一种思路:由于题目要求使得组的上界最小,那么我们就可以通过判断条件来约束,如何约束呢,如果我们发现一个组还没有匹配人,那直接匹配,因为1一定是最小值,如果不是第一次匹配,那就让匹配他的人再去匹配其他人,匹配规则依然是这样的,但如果有一个节点不满足上述情况,意思就是这个结点所连的所有组都已经被别人匹配过了,那么就直接选第一个与其进行匹配就可以了,但是这里出问题了,因为我们不能确定第一个匹配的人就是匹配之后的最小值,因为这个值肯定要加到最小值上才不会影响答案.so下面二分答案.
 
二分答案:
  二分答案,每次用匹配check,如果改上界可以使得完备匹配,那么就改变r,否则改变l,然后ok.输出mid.
 /*************************************************************************
> File Name: poj-2289.jamies_contact_groups.cpp
> Author: CruelKing
> Mail: 2016586625@qq.com
> Created Time: 2019年09月03日 星期二 21时09分58秒
************************************************************************/
/*
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
using namespace std; const int maxn = 1000 + 5, maxm = 500 + 5, inf = 0x3f3f3f3f; int n, m;
string str;
char name[20];
int linker[maxm][maxn];
bool used[maxm], g[maxn][maxm]; bool dfs(int u) {
for(int v = 0; v < m; v ++) {
if(g[u][v] && !used[v]) {
used[v] = true;
if(linker[v][0] == 0) {
linker[v][++ linker[v][0]] = u;
return true;
}
for(int i = 1; i <= linker[v][0]; i ++) {
if(dfs(linker[v][i])) {
linker[v][i] = u;
return true;
}
}
linker[v][++ linker[v][0]] = u;
return true;
}
}
return false;
} int main() {
while(cin >> n >> m && (n || m)) {
memset(g, false, sizeof g);
for(int i = 0; i < n; i ++) {
cin >> name;
getline(cin, str);
stringstream ss;
ss << str;
int x;
while(ss >> x)
g[i][x] = true;
}
int res = 0;
for(int i = 0; i < m; i ++) linker[i][0] = 0;
for(int i = 0; i < n; i ++) {
memset(used, false, sizeof used);
if(dfs(i)) res ++;
}
int M = 0;
for(int i = 0; i < m; i ++) {
if(M < linker[i][0]) M = linker[i][0];
}
cout << M << endl;
}
return 0;
}
*/
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#define mid ((l + r) >> 1)
using namespace std; const int maxn = + , maxm = + , inf = 0x3f3f3f3f; int n, m, l, r;
string str;
char name[];
int linker[maxm][maxn];
bool used[maxm], g[maxn][maxm]; bool dfs(int u) {
for(int v = ; v < m; v ++) {
if(g[u][v] && !used[v]) {
used[v] = true;
if(linker[v][] < mid) {
linker[v][++ linker[v][]] = u;
return true;
}
for(int i = ; i <= mid; i ++) {
if(dfs(linker[v][i])) {
linker[v][i] = u;
return true;
}
}
}
}
return false;
} int main() {
while(cin >> n >> m && (n || m)) {
memset(g, false, sizeof g);
for(int i = ; i < n; i ++) {
cin >> name;
getline(cin, str);
stringstream ss;
ss << str;
int x;
while(ss >> x)
g[i][x] = true;
}
/*
int res = 0;
l = 0, r = maxn << 1;
for(int i = 0; i < m; i ++) linker[i][0] = 0;
for(int i = 0; i < n; i ++) {
memset(used, false, sizeof used);
if(dfs(i)) res ++;
}
cout << res << endl;
*/
l= , r = n;
int res;
while(l <= r) {
res = ;
for(int i = ; i < m; i ++) linker[i][] = ;
for(int i = ; i < n; i ++) {
memset(used, false, sizeof used);
if(dfs(i)) res ++;
}
if(n == res) r = mid - ;
else l = mid + ;
}
cout << mid + << endl;
}
return ;
}

poj-2289.jamies contact groups(二分答案 + 二分多重匹配)的更多相关文章

  1. 【CF981F】Round Marriage(二分答案,二分图匹配,Hall定理)

    [CF981F]Round Marriage(二分答案,二分图匹配,Hall定理) 题面 CF 洛谷 题解 很明显需要二分. 二分之后考虑如果判定是否存在完备匹配,考虑\(Hall\)定理. 那么如果 ...

  2. LibreOJ &num;2006&period; 「SCOI2015」小凸玩矩阵 二分答案&plus;二分匹配

    #2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  3. 【BZOJ4443】小凸玩矩阵(二分答案,二分图匹配)

    [BZOJ4443]小凸玩矩阵(二分答案,二分图匹配) 题面 BZOJ Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两 ...

  4. POJ 2289 Jamie&&num;39&semi;s Contact Groups 【二分】&plus;【多重匹配】&lpar;模板题&rpar;

    <题目链接> 题目大意: 有n个人,每个人都有一个或者几个能够归属的分类,将这些人分类到他们能够归属的分类中后,使所含人数最多的分类值最小,求出该分类的所含人数值. 解题分析: 看到求最大 ...

  5. Leetcode 4 Median of Two Sorted Arrays 二分查找(二分答案&plus;二分下标)

    貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的... 题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数. 二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第 ...

  6. POJ 3189 Steady Cow Assignment 【二分】&plus;【多重匹配】

    <题目链接> 题目大意: 有n头牛,m个牛棚,每个牛棚都有一定的容量(就是最多能装多少只牛),然后每只牛对每个牛棚的喜好度不同(就是所有牛圈在每个牛心中都有一个排名),然后要求所有的牛都进 ...

  7. D&period; Black Hills golden jewels 二分答案 &plus; 二分判定

    http://codeforces.com/gym/101064/problem/D 题目是给定一个数组,如果两两组合,有C(n, 2)种结果,(找出第一个大于等于第k大的结果) 思路, 二分答案va ...

  8. 【POJ 1698】Alice&&num;39&semi;s Chance(二分图多重匹配)

    http://poj.org/problem?id=1698 电影和日子匹配,电影可以匹配多个日子. 最多有maxw*7个日子. 二分图多重匹配完,检查一下是否每个电影都匹配了要求的日子那么多. #i ...

  9. 【洛谷4251】 &lbrack;SCOI2015&rsqb;小凸玩矩阵(二分答案,二分图匹配)

    题面 传送门 Solution 看到什么最大值最小肯定二分啊. check直接跑一个二分图匹配就好了. orz ztl!!! 代码实现 /* mail: mleautomaton@foxmail.co ...

随机推荐

  1. git clone错误

    git clone错误 Initialized empty Git repository in ***/.git/ error: The requested URL returned error: 4 ...

  2. 我常用的Mac快捷键

    1. 最小化当前窗口 command m 2. 在不同应用间切换 command tab 3. 在同一应用的不同窗口间切换 command ` 4. 在浏览器同一窗口的不同标签间切换 ctrl tab ...

  3. 查看LINUX当前负载

    Linux的负载高,主要是由于CPU使用.内存使用.IO消耗三部分构成.任意一项使用过多,都将导致服务器负载的急剧攀升. [root@ok Desktop]# w 20:41:47 up  2:48, ...

  4. Android UI-开源框架ImageLoader的完美例子

    Android开源框架ImageLoader的完美例子 2013年8月19日开源框架之Universal_Image_Loader学习 很多人都在讨论如何让图片能在异步加载更加流畅,可以显示大量图片, ...

  5. nagios的安装与部署

    参考文献: https://www.cnblogs.com/mchina/archive/2013/02/20/2883404.html https://www.jianshu.com/p/3476d ...

  6. 不裸缩点》。。。POJ2186受欢迎的牛

    不裸缩点>...POJ2186受欢迎的牛 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: ...

  7. &lbrack;笔记&rsqb; ubuntu下添加windows的字体

    方法如下: 第一步:将windows下喜欢的字体文件copy到一个文件夹中,例如将XP里WINDOWS/FONTS中的字体文件(本人比较贪心,把整个文件夹copy了过来……),在linux中命名为xp ...

  8. Repeter中列相同数据合并

    <asp:Repeater runat="server" ID="rptInfo" onitemdatabound="Repeater1_Ite ...

  9. c&num;版flappybird 未完全实现

    这些天开始在深圳找工作,想着把从前有些淡忘的技术再温故下.看到尊敬的<传智播客>有一期公开课,讲的是用c#编写flappybird小游戏,也就自己搜了下游戏资源,也来试试看. 其实用到的技 ...

  10. mysql INNER&sol;LEFT&sol;RIGHT JOIN区别

    1.创建table DROP TABLE IF EXISTS `tab_id_index`; CREATE TABLE `tab_id_index` ( `id` ) ', `name` ) DEFA ...