题目大意:

有n个人,可以分成m个组,现在给出你每个人可以去的组的编号,求分成的m组中人数最多的组最少可以有多少人。

算法讨论:

首先喷一下这题的输入,太恶心了。

然后说算法:最多的最少,二分的字眼。二分什么,因为我们说的是组的人,所以要对组的流出量进行二分。其余的都连流量为1的边,然后对“小组”点的流出量二分连边,最后跑最大流判断

是否等于N即可。还是蛮简单的。

Codes:

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std; struct Edge{
int from, to, cap, flow;
Edge(int _from=, int _to=, int _cap=, int _flow=):
from(_from), to(_to), cap(_cap), flow(_flow) {}
}E[ + ]; struct Dinic{
static const int N = + ;
static const int M = + ;
static const int oo = 0x3f3f3f3f; int n, m, s, t;
vector <Edge> edges;
vector <int> G[N];
int cur[N], dis[N];
bool vi[N]; void Clear(){
for(int i = ; i <= n; ++ i) G[i].clear();
edges.clear();
}
void Add(int from, int to, int cap, int flow){
edges.push_back((Edge){from, to, cap, });
edges.push_back((Edge){to, from, , });
int m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool bfs(){
memset(vi, false, sizeof vi);
dis[s] = ; vi[s] = true;
queue <int> q;
q.push(s);
while(!q.empty()){
int x = q.front(); q.pop();
for(int i = ; i < G[x].size(); ++ i){
Edge &e = edges[G[x][i]];
if(!vi[e.to] && e.cap > e.flow){
vi[e.to] = true;
dis[e.to] = dis[x] + ;
q.push(e.to);
}
}
}
return vi[t];
}
int dfs(int x, int a){
if(x == t || a == ) return a;
int flw = , f;
for(int &i = cur[x]; i < G[x].size(); ++ i){
Edge &e = edges[G[x][i]];
if(dis[x] + == dis[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > ){
e.flow += f; edges[G[x][i]^].flow -= f;
a -= f; flw += f;
if(a == ) break;
}
}
return flw;
}
int MaxFlow(int s, int t){
this->s = s; this->t = t;
int flw = ;
while(bfs()){
memset(cur, , sizeof cur);
flw += dfs(s, oo);
}
return flw;
}
}Net; int n, m;
char buf[];
int len, cnt = , x, np;
int bj[ + ];
int l, r, mid; bool check(int mv){
Net.Clear();
for(int i = ; i <= n; ++ i)
Net.Add(, i, , );
for(int i = ; i <= cnt; ++ i)
Net.Add(E[i].from, E[i].to, , );
for(int i = n + ; i <= n + m; ++ i)
Net.Add(i, n + m + , mv, );
return Net.MaxFlow(, n + m + ) == n;
} void Solve(){
int ans, l = ;
while(l <= r){
mid = l + (r - l) / ;
if(check(mid)){
ans = mid; r = mid - ;
}
else l = mid + ;
}
printf("%d\n", ans);
return;
}
int main(){ while(scanf("%d%d", &n, &m) && n && m){
cnt = ;r = ;
memset(bj, , sizeof bj);
Net.n = n + m + ;
for(int i = ; i <= n; ++ i){
getchar();gets(buf);
len = strlen(buf);
for(int j = ; j < len;){
if(buf[j] < '' || buf[j] > ''){
j ++; continue;
}
while(buf[j] <= '' && buf[j] >= ''){
x = x * + buf[j] - '';j ++;
}
++ cnt;
E[cnt] = (Edge){i, x + + n, , };
bj[E[cnt].to] ++;
r = max(bj[E[cnt].to], r);
x = ;
}
}
Solve();
}
return ;
}

POJ 2289

POJ 2289 Jamie's Contact Groups (二分+最大流)的更多相关文章

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

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

  2. 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 ...

  3. poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】

    题目链接:http://poj.org/problem?id=2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K ...

  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 & POJ3189 Steady Cow Assignment

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

  7. 图论--网络流--最大流 POJ 2289 Jamie's Contact Groups (二分+限流建图)

    Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very ...

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

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

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

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

随机推荐

  1. Maybe I go too extreme

    昨天拖着一个没睡好的身体去面试了2家公司 被问到Collection的子集的时候顿时傻了一会,明明很简单的问题一时就想不起来了,哈哈.果然做it的人身体要顾好,状态太差了. 发现了一个问题,其实也是早 ...

  2. ci 的控制器文件夹下开加子文件夹

    在一个比较大的项目中,希望controllers下再细分子文件夹.例如:controllers/pj,controllers/xxk等. 做法是: 1.在controllers下添加相关的子文件夹,例 ...

  3. sqlalchemy操作Mysql

    SQLAlchemy“采用简单的Python语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型”.SQLAlchemy的理念是,SQL数据库的量级和性能重要于对象集合:而对象集合的抽象又 ...

  4. project euler 14 collatz

    def collatz(num,i): i =i + 1 if num%2 == 0: return collatz(num//2,i) elif num == 1: return i else: r ...

  5. Linux免SSH密码登录

    SSH免密码登录,做个总结吧! 1.安装SSH服务(略过) 2.场景:需要配置主机A无密码登录主机B 在主机A上执行如下: cd ~/.ssh ssh-keygen -t rsa 生成密钥文件 cp ...

  6. iOS -多字体混合

    label 加下划线 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 300, 100)];    label.b ...

  7. 蓝牙芯片NRF51822入门学习1:时间管理

    前言 之前辞职找工作的时候发现,很多公司希望招聘蓝牙技术方面的人才,所以干脆丢开LWIP静下心来学习蓝牙技术.原本以为一两星期能基本学会的,谁知道所选的蓝牙芯片nrf51822是个坑货,坑了我一个月. ...

  8. Windows 8.1 Update1 6610 32位/64位下载、安装和新增功能简评

    今天,微软已经确认完成Windows 8.1 2014 Update RTM正式版的开发工作,累计修复99%的已知bug.随后,微软会将Win8.1首个春季更新正式版,即Win8.1 2014 Upd ...

  9. AnimateWindow

    WINDOWS提供了一个很有意思的函数:AnimateWindow.之前我想实现像MSN,QQ这些收到邮件的时候动画方式,从地下升上来的显示一个窗口,感觉很麻烦,自己去写代码,效果很不理想,今天无意中 ...

  10. 《Programming WPF》翻译 第5章 2.内嵌样式

    原文:<Programming WPF>翻译 第5章 2.内嵌样式 每一个“可样式化”的WPF元素都有一个Style属性,可以在内部设置这个属性--使用XAML属性-元素的语法(在第一章讨 ...