POJ 2289 Jamie's Contact Groups (二分+最大流)
题目大意:
有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 (二分+最大流)的更多相关文章
- Poj 2289 Jamie's Contact Groups (二分+二分图多重匹配)
题目链接: Poj 2289 Jamie's Contact Groups 题目描述: 给出n个人的名单和每个人可以被分到的组,问将n个人分到m个组内,并且人数最多的组人数要尽量少,问人数最多的组有多 ...
- 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 ...
- poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】
题目链接:http://poj.org/problem?id=2289 Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 65536K ...
- POJ 2289——Jamie's Contact Groups——————【多重匹配、二分枚举匹配次数】
Jamie's Contact Groups Time Limit:7000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I ...
- POJ 2289 Jamie's Contact Groups 二分图多重匹配 难度:1
Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 6511 Accepted: ...
- POJ 2289 Jamie's Contact Groups & POJ3189 Steady Cow Assignment
这两道题目都是多重二分匹配+枚举的做法,或者可以用网络流,实际上二分匹配也就实质是网络流,通过枚举区间,然后建立相应的图,判断该区间是否符合要求,并进一步缩小范围,直到求出解.不同之处在对是否满足条件 ...
- 图论--网络流--最大流 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 ...
- POJ 2289 Jamie's Contact Groups(多重匹配+二分)
题意: Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是 ...
- POJ 2289 Jamie's Contact Groups 【二分】+【多重匹配】(模板题)
<题目链接> 题目大意: 有n个人,每个人都有一个或者几个能够归属的分类,将这些人分类到他们能够归属的分类中后,使所含人数最多的分类值最小,求出该分类的所含人数值. 解题分析: 看到求最大 ...
随机推荐
- C++访问声明
代码: #include <iostream> #include <string> using namespace std; struct B{ private: int s; ...
- [转载]Git常用命令
转载自: Git常用命令 Git配置 git config --global user.name "robbin" git config --global user.email & ...
- 多线程中遇到ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);怎么解决
XP下用VC开发的程序,在一个主线程调用3 个线程,线程之间要共享数据,结果总出现wincore.cpp line 980 ASSERT(pMap-> LookupPermane ...
- js与webview 常用交互代码
常用js交互 css常用参数::: 是否允许用户选择元素的内容,选择值包括: auto:用户可以选择元素内的内容 none:用户不能选择任何内容 text:用户只能选择元素内的 ...
- Android处理XML的三种方式
http://www.cnblogs.com/zhangdongzi/archive/2011/04/14/2016434.html http://blog.csdn.net/zzp16/articl ...
- delphi 打开文件夹并定位到一个文件(关键是/select参数)
strFileName := FcxLV[nIndex].Items.Item[FcxLV[nIndex].ItemIndex].SubItems.Strings[0]; //路径 ShellExe ...
- 图解SSL/TLS协议(转)
本周,CloudFlare宣布,开始提供Keyless服务,即你把网站放到它们的CDN上,不用提供自己的私钥,也能使用SSL加密链接. 我看了CloudFlare的说明(这里和这里),突然意识到这是绝 ...
- mybatis和hibernate对比
Hibernate是一个数据库表和java对象之间完全映射的框架,java开发人员直接对java对象操作,而不对数据库表进行操作: Mybatis是对SQL语句和java对象进行映射,仍需要开发人员编 ...
- cf486B OR in Matrix
B. OR in Matrix time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- Find the Duplicate Number 解答
Question Given an array nums containing n + 1 integers where each integer is between 1 and n (inclus ...