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 #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

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

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

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

  4. POJ 2289 Jamie's Contact Groups 【二分】+【多重匹配】(模板题)

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

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

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

  6. POJ 3189 Steady Cow Assignment 【二分】+【多重匹配】

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

  7. D. Black Hills golden jewels 二分答案 + 二分判定

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

  8. 【POJ 1698】Alice's Chance(二分图多重匹配)

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

  9. 【洛谷4251】 [SCOI2015]小凸玩矩阵(二分答案,二分图匹配)

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

随机推荐

  1. C#基础知识之扩展方法

    扩展方法需要满足的条件: 1.扩展方法必须定义在静态类里. 2.扩展方法必须是静态方法. 3.扩展方法的第一个参数以this修饰符为前缀. 4.扩展方法必须在使用它的类的扩展方法内,否则必须显示的us ...

  2. IP地址与子网掩码逐位相与

    逐位相与说的其实就是子网掩码与网络地址相同位置的数字相加,当和为2的时候该位置写作1,否则的话写作0

  3. AGC007题解

    发现自己思维能力又跟不上了...做题有点吃力...所以回归AGC刷题计划... AGC040506都写了一部分题然后懒得补全了,所以从07开始做吧.大概是从C开始. C 这也太人类智慧了吧... 我先 ...

  4. MySQL数据库4Python操作mysql、索引、慢查询日志

    目录 一.Python 操作 mysql 1.1python 操作 mysql 1.2查询数据 1.3增加(添加.更新)数据 1.4修改数据 1.5删除数据 1.6SQL注入问题 1.6.1问题的引入 ...

  5. Java调用Fortran生成so库报“libifport.so.5: 无法打开共享对象文件”错误解决方法

    source /opt/intel/bin/compilervars.sh intel64

  6. LeetCode--015--三数之和(python)

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 先对nums进行排序,再用双指针,L ...

  7. delphi 10.3 IOS中英文错位

    delphi 每回升级都会遇到各种问题, 在安卓和windows下正常,ios遇到排版问题. 解决办法:将附件文件放至程序目录下. 百度网盘下载附件 链接: https://pan.baidu.com ...

  8. Rosetta Stone 不在C盘安装步骤

    本文出自:http://www.cnblogs.com/2186009311CFF/p/7500637.html Rosetta Stone默认安装在C盘的,很不好,故找到次解决方案: 总体就是移动文 ...

  9. HTML和CSS实现的透明登录框效果

    实现代码 HTML部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  10. SQL server 字段合并CAST(org_no AS VARCHAR(20))+CAST(page_no AS VARCHAR(20))+CAST(djlb_no AS VARCHAR(20)))

    sql server 字段合并(CAST) ---------------------- select (CAST(org_no AS VARCHAR(20))+CAST(page_no AS VAR ...