Jamie's Contact Groups
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 8473   Accepted: 2875

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

题意:
  N个人,M个组,给出每个人可以考虑选择的组号,要求每个人都必须选且只能选一个组,求一个划分方案使得最多人数的组的人数 是所有方案中人数最少的,结果输出这个最小值。

题解:

  一对多的二分图多重匹配问题。网络流建图:源点到每个人连边,边权为1;每个人到可以考虑选择的组连边,边权为1;每个组到汇点连边,边权为求解的最小值。这个最小值很明显可以想到二分求解。

代码:

 #include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int N = ;
const int M = 1e6;
const int inf = 1e9;
int n, m, S, T;
int dep[N], cur[N];
int head[N];
struct Edge{
int v, c, nex;
Edge(int _v=,int _c=,int _nex=):v(_v),c(_c),nex(_nex){}
}E[M]; int cnt;
void add(int u, int v, int c){
E[cnt].v = v;
E[cnt].c = c;
E[cnt].nex = head[u];
head[u] = cnt++;
} bool bfs() {
queue<int> q;
memset(dep, -, sizeof(dep));
q.push(S); dep[S] = ;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = E[i].nex) {
int v = E[i].v;
if(E[i].c && dep[v] == -) {
dep[v] = dep[u] + ;
q.push(v);
}
}
}
return dep[T] != -;
}
int dfs(int u, int flow) {
if(u == T) return flow;
int w, used=;
for(int i = head[u]; ~i; i = E[i].nex) {
int v = E[i].v;
if(dep[v] == dep[u] + ) {
w = flow - used;
w = dfs(v, min(w, E[i].c));
E[i].c -= w; E[i^].c += w;
if(v) cur[u] = i;
used += w;
if(used == flow) return flow;
}
}
if(!used) dep[u] = -;
return used;
}
int dinic() {
int ans = ;
while(bfs()) {
for(int i = ; i <= T;i++)
cur[i] = head[i];
ans += dfs(S, inf);
}
return ans;
}
int main() {
char s[];
int i, j, x, t;
while(~scanf("%d%d", &n, &m),n+m) {
memset(head, -, sizeof(head));
cnt = ;
S = n+m+; T = n+m+;
vector<int>g[N];
for(i = ; i <= n; ++i) g[i].clear();
for(i = ; i < n; ++i) {
scanf("%s", s);
while(getchar() != '\n') {
scanf("%d", &x);
g[i].push_back(x);
}
}
int l = , r = n, mid;
while(l <= r) {
memset(head, -, sizeof(head));
cnt = ;
mid = (l+r)/;
for(i = ; i < n; ++i) {
for(j = ; j < g[i].size(); ++j)
add(i, n+g[i][j], ),add(n+g[i][j], i, );
}
for(i = ; i < n; ++i) add(S,i,), add(i,S,);
for(i = n; i < n+m; ++i) add(i,T,mid),add(T,i,);
t = dinic();
if(t == n) r = mid - ;
else l = mid + ;
}
printf("%d\n", l);
}
}

485ms

poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】的更多相关文章

  1. POJ 2289 Jamie's Contact Groups (二分+最大流)

    题目大意: 有n个人,可以分成m个组,现在给出你每个人可以去的组的编号,求分成的m组中人数最多的组最少可以有多少人. 算法讨论: 首先喷一下这题的输入,太恶心了. 然后说算法:最多的最少,二分的字眼. ...

  2. Poj 2289 Jamie's Contact Groups (二分+二分图多重匹配)

    题目链接: Poj 2289 Jamie's Contact Groups 题目描述: 给出n个人的名单和每个人可以被分到的组,问将n个人分到m个组内,并且人数最多的组人数要尽量少,问人数最多的组有多 ...

  3. POJ 2289 Jamie's Contact Groups / UVA 1345 Jamie's Contact Groups / ZOJ 2399 Jamie's Contact Groups / HDU 1699 Jamie's Contact Groups / SCU 1996 Jamie's Contact Groups (二分,二分图匹配)

    POJ 2289 Jamie's Contact Groups / UVA 1345 Jamie's Contact Groups / ZOJ 2399 Jamie's Contact Groups ...

  4. POJ 2289——Jamie's Contact Groups——————【多重匹配、二分枚举匹配次数】

    Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I ...

  5. POJ 2289 Jamie's Contact Groups 二分图多重匹配 难度:1

    Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 6511   Accepted: ...

  6. POJ 2289 Jamie's Contact Groups(多重匹配+二分)

    题意: Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是 ...

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

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

  8. POJ 2289 Jamie's Contact Groups & POJ3189 Steady Cow Assignment

    这两道题目都是多重二分匹配+枚举的做法,或者可以用网络流,实际上二分匹配也就实质是网络流,通过枚举区间,然后建立相应的图,判断该区间是否符合要求,并进一步缩小范围,直到求出解.不同之处在对是否满足条件 ...

  9. POJ - 2289 Jamie's Contact Groups (二分图多重匹配)

    题意:N个人,M个团体.每个人有属于自己的一些团体编号.将每个人分配到自己属于的团体中,问这个人数最多的团体其人数最小值是多少. 分析:一个一对多的二分图匹配,且是最大值最小化问题.二分图的多重匹配建 ...

随机推荐

  1. AngularJS内建服务以及自定义服务的用法

    在AngularJS中, 服务是一个比较重要的部分,它是一个对象或者是函数,可以在你的AngularJS的应用中使用.接下来介绍几种比较常用的内建服务以及自定义服务的方法. [内建服务] (1)loc ...

  2. [Redis] redis数据备份恢复与持久化

    数据库备份,使用save命令,将会在redis的安装目录中生成dump.rdb 例如:在我的目录下 redis/src/dump.rdb 使用命令config get dir,获取当前redis的安装 ...

  3. 二十一、curator recipes之TreeCache

    简介 curator的TreeCache允许对某个路径的数据和路径变更以及其下所有子孙节点的数据和路径变更进行监听. 官方文档:http://curator.apache.org/curator-re ...

  4. win32FTP程序设计

    掌握socket基于事件机制的网络程序设计,掌握多线程技术的FTP Server端设计方法,掌握FTP标准基本协议及其程序的实现,掌握文件内容的网络传输设计方法. 利用CFtpServer类接收和解析 ...

  5. C Traps:运算

    位移 如果sizeof(int) = 4,那么下面的代码的结果是什么? int x=255; printf("%d", x>>34); 实际输出:63 在编译这个代码时 ...

  6. xshell复制粘贴

    用户看到这个标题肯定会觉得小编脑子坏掉了,复制粘贴不就是Ctrl+C,Ctrl+V嘛,但是在xshell却不尽然. 现象: 在xshell界面中需要用到之前的一段代码,自然是选中,熟练的键入Ctrl+ ...

  7. ECMAScript 5和ECMAScript6的新特性以及浏览器支持情况

    ECMAScript简介: 它是一种由Ecma国际(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范,javascript在它基础上经行了自己的封装.但通常来说,术语ECMAScript和java ...

  8. CF 827E Rusty String FFT

    传送门 如果没有碍事的?的话,判定字符串的循环节直接用KMP的失配数组就可以搞定.现在有了碍事的?,我们就需要考虑更通用的算法. 考虑KMP失配数组判定字符串循环节的本质,发现判定\(k\)是否为字符 ...

  9. css固定广告栏

    <div style="position: fixed; left: 50%; top: 100px; margin-left: -621px;"> <div&g ...

  10. Python解析SWAN气象雷达数据--(解析、生成ASCII、Image、netCDF)

    解析   from datetime import * import time import calendar import json import numpy as np from struct i ...