题目大意:你的手机通讯录里有n个联系人,m个分组,其中,有的联系人在多个分组里。你的任务是在一些分组里删除一些联系人,使得每个联系人只在一个分组里并且使人数最多的那个分组人数最少。找出人数最多的那个分组中的人数。

题目分析:要求的是最小的最大值,二分枚举这个最小的最大人数x。增加源点s和汇点t,从s向每一个联系人连一条弧,容量为1,表示一个联系人只能在一个分组中;然后对于每个联系人向他所在的分组连一条弧,容量为1,表示在这个分组里最多保存一次该联系人;然后从每个分组向汇点连一条弧,容量为x,表示这个分组不能保存超过x个联系人。求最大流,如果源点s出发的每条边都满载,说明x可行。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; # define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b) const double inf=1e30;
const int INF=1<<30;
const int N=1505; struct Edge
{
int fr,to,cap,fw;
Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
};
vector<Edge>edges,tedges;
vector<int>G[N];
int cur[N],vis[N],d[N],mark[505]; void init(int n)
{
edges.clear();
REP(i,0,n) G[i].clear();
} void addEdge(int u,int v,int cap)
{
edges.push_back(Edge(u,v,cap,0));
edges.push_back(Edge(v,u,0,0));
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
} bool BFS(int s,int t)
{
CL(vis,0);
vis[s]=1;
d[s]=0;
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
REP(i,0,G[u].size()){
Edge &e=edges[G[u][i]];
if(!vis[e.to]&&e.cap>e.fw){
d[e.to]=d[u]+1;
vis[e.to]=1;
q.push(e.to);
}
}
}
return vis[t];
} int DFS(int u,int t,int a)
{
if(u==t||a==0) return a;
int flow=0,f;
for(int &i=cur[u];i<G[u].size();++i){
Edge &e=edges[G[u][i]];
if(d[e.to]==d[u]+1&&(f=DFS(e.to,t,min(a,e.cap-e.fw)))>0){
e.fw+=f;
edges[G[u][i]^1].fw-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
} int Dinic(int s,int t)
{
int flow=0;
while(BFS(s,t)){
CL(cur,0);
flow+=DFS(s,t,INF);
}
return flow;
} bool read(int &x)
{
x=0;
char c;
while(c=getchar()){
if(c==' ') return true;
else if(c=='\n') return false;
else x=x*10+c-'0';
}
} bool judge()
{
REP(i,0,G[0].size())
if(edges[G[0][i]].cap>0&&edges[G[0][i]].cap!=edges[G[0][i]].fw) return false;
return true;
} int main()
{
int n,m;
char name[20];
while(scanf("%d%d",&n,&m)&&(n+m))
{
init(n+m+2);
CL(mark,0);
REP(i,1,n+1){
cin>>name;
addEdge(0,m+i,1);
int a;
getchar();
while(read(a)){
++mark[a];
addEdge(m+i,a+1,1);
}
addEdge(m+i,a+1,1);
++mark[a];
} int cnt=edges.size();
tedges.clear();
REP(i,0,cnt) tedges.push_back(edges[i]); int l=0,r=0;
REP(i,0,m) r=max(r,mark[i]);
while(l<r){
int mid=l+(r-l)/2;
init(n+m+2);
REP(i,0,cnt) addEdge(tedges[i].fr,tedges[i].to,tedges[i].cap);
REP(i,0,m) if(mark[i])
addEdge(i+1,n+m+1,min(mid,mark[i]));
Dinic(0,n+m+1);
if(judge()) r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}

  

UVALive-3268 Jamie's Contact Groups (最大流,网络流建模)的更多相关文章

  1. POJ2289 Jamie's Contact Groups —— 二分图多重匹配/最大流 + 二分

    题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 6 ...

  2. Jamie's Contact Groups POJ - 2289(多重匹配 最大值最小化 最大流)

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

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

  5. POJ2289 Jamie's Contact Groups(二分图多重匹配)

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

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

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

  7. POJ2289:Jamie's Contact Groups(二分+二分图多重匹配)

    Jamie's Contact Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/ ...

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

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

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

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

  10. 图论--网络流--最大流 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 ...

随机推荐

  1. SpringIoc的精彩讲解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  2. 解决命令行执行shell脚本成功,但crontab执行失败

    实际生产案例 生产机房自建PPTP客户端通过拨号连接到生产机房,但是一旦客户端网络是意外断线再重新拨号 会产生IP冲突,于是写了一个脚本监控PPTP的IP是否有多个(一般冲突以后会生成2个IP) #! ...

  3. CodeForces 19D Points (线段树+set)

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  4. 焦作网络赛B-Mathematical Curse【dp】

    A prince of the Science Continent was imprisoned in a castle because of his contempt for mathematics ...

  5. __devexit_p的功能

    看驱动的时候,时常会有如下代码: .remove = __devexit_p(XX_exit), 这里的__devexit_p有什么作用呢? 我在include/linux/init.h中找到了它的定 ...

  6. django-mvvm(django的FormObject)

    MVVM简介 MVVM模式是Model-View-ViewMode模式的简称.由视图(View).视图模型(ViewModel).模型(Model)三部分组成,结构如下图.通过这三部分实现UI逻辑.呈 ...

  7. Linux eventfd分析

    2017-07-20 eventfd在linux中是一个较新的进程通信方式,和信号量等不同的是event不仅可以用于进程间的通信,还可以用户内核发信号给用户层的进程.eventfd在virtIO后端驱 ...

  8. mysql 数据操作 单表查询 limit 限制查询的记录数

    mysql; +----+-----------+------+-----+------------+---------+--------------+------------+--------+-- ...

  9. MongDb的安装

    MongoDB是一个基于分布式文件存储的数据库,由c++语言编写,为WEB应用提供可扩展的高性能数据存储解决方案.MongoDB属于非关系数据库,也不能说完全属于,更像是介于关系数据库和非关系数据库之 ...

  10. 配置Tomcat直接显示目录结构和文件列表

    Tomcat是直接显示目录结构和文件列表,只是在配置里面给关闭了. 关键在这里:\conf\web.xml 这个文件有一段配置直接控制Tomcat是允许显示目录结构和文件列表. <servlet ...