poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】
| Time Limit: 7000MS | Memory Limit: 65536K | |
| Total Submissions: 8473 | Accepted: 2875 |
Description
Input
Output
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;每个人到可以考虑选择的组连边,边权为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【二分+最大流】【二分图多重匹配问题】的更多相关文章
- POJ 2289 Jamie's Contact Groups (二分+最大流)
题目大意: 有n个人,可以分成m个组,现在给出你每个人可以去的组的编号,求分成的m组中人数最多的组最少可以有多少人. 算法讨论: 首先喷一下这题的输入,太恶心了. 然后说算法:最多的最少,二分的字眼. ...
- 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——————【多重匹配、二分枚举匹配次数】
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(多重匹配+二分)
题意: Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是 ...
- POJ 2289 Jamie's Contact Groups 【二分】+【多重匹配】(模板题)
<题目链接> 题目大意: 有n个人,每个人都有一个或者几个能够归属的分类,将这些人分类到他们能够归属的分类中后,使所含人数最多的分类值最小,求出该分类的所含人数值. 解题分析: 看到求最大 ...
- POJ 2289 Jamie's Contact Groups & POJ3189 Steady Cow Assignment
这两道题目都是多重二分匹配+枚举的做法,或者可以用网络流,实际上二分匹配也就实质是网络流,通过枚举区间,然后建立相应的图,判断该区间是否符合要求,并进一步缩小范围,直到求出解.不同之处在对是否满足条件 ...
- POJ - 2289 Jamie's Contact Groups (二分图多重匹配)
题意:N个人,M个团体.每个人有属于自己的一些团体编号.将每个人分配到自己属于的团体中,问这个人数最多的团体其人数最小值是多少. 分析:一个一对多的二分图匹配,且是最大值最小化问题.二分图的多重匹配建 ...
随机推荐
- DHU 1788 Chinese remainder theorem again 中国剩余定理
Chinese remainder theorem again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 ...
- zookeeper 典型应用
一.发布/订阅 配置文件的集中管理. 问题:当分布式系统变多后,每个系统保存相应的配置文件,会造成同个文件有多份,修改起来非常麻烦. 解决方法:使用zk的发布/订阅功能,配合Watcher机制,在应用 ...
- php判断是否isPhone、is_weixin
protected function isPhone(){ $agent = strtolower($_SERVER['HTTP_USER_AGENT']); //pc请求头信息数组 $pc_arr= ...
- linux解压tar.gz
gnuzip或者tar -zxvf file.tar.gz unzip file.zip
- springboot 文件上传和下载
文件的上传和下载 1.文件上传 html页面代码如下 <form method="post" action="/file/upload1" enctype ...
- scss-!optional
optional翻译成汉语具有"可选的"的意思.顾名思义,!optional标记前面的扩展不必须生成一个新的选择器.看一段SCSS代码片段: p{ color:red; @exte ...
- 转:php中判断某个IP地址是否存在范围内
原文:php中判断某个IP地址是否存在范围内 //案例:判断192.168.1.127是否在 (192.168.1.1--192.168.1.255)的范围里面 $ip_start = get_ipl ...
- python爬虫笔记----4.Selenium库(自动化库)
4.Selenium库 (自动化测试工具,支持多种浏览器,爬虫主要解决js渲染的问题) pip install selenium 基本使用 from selenium import webdriver ...
- 【vue】vue的路由权限管理
前言: 最近闲来无事浏览各种博客,看到了一个关于路由权限的管理,觉得很有用,针对那个博客,准备自己写一个demo. 实现: 路由大致分为用户路由<特定用户才能浏览>和基本路由<所有用 ...
- hihocoder [Offer收割]编程练习赛12 [1494] ---- 一面砖墙
原题链接 一面砖墙 算法分析 设墙的宽度为 range,则需要统计横坐标为 1,2,3,4,...,range-1 处的墙缝数,取最大的墙缝数(记为maxCrevices),从该处划一道竖线,竖线穿过 ...