题目大意:你的手机通讯录里有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. Day06 DOM4J&schema介绍&xPath

    day06总结 今日内容 XML解析之JAXP( SAX ) DOM4J Schema   三.XML解析器介绍   操作XML文档概述   1 如何操作XML文档 XML文档也是数据的一种,对数据的 ...

  2. 003-and design-在create-react-app项目中使用antd

    一.概述 create-react-app 是业界最优秀的 React 应用开发工具之一,本文会尝试在 create-react-app 创建的工程中使用 antd 组件,并自定义 webpack 的 ...

  3. sysbench 0.4.12安装

    前提:mysql已安装完成,请参考http://www.cnblogs.com/lizhi221/p/6813907.html   安装依赖环境包: yum install -y bzr yum in ...

  4. 线程,协程,IO模型

    理论: 1.每创造一个进程,默认里面就有一个线程 2.进程是一个资源单位,而进程里面的线程才是CPU上的一个调度单位 3.一个进程里面的多个线程,是共享这个进程里面的资源的 4.线程创建的开销比进程要 ...

  5. js判断display隐藏显示

    // 判断是否为隐藏(css)样式 function isHide(obj) {   var ret = obj.style.display === "none" || obj.s ...

  6. C语言的 32个关键之和9个控制语言之关键字

    auto   break  case  char  const  continue  default  do double  else  enum  extern  float for  goto  ...

  7. flask应用中取得config的配置

    from flask import current_app config = current_app.config SITE_DOMAIN = config.get('SITE_DOMAIN')

  8. python webdriver 报错WebDriverException: Message: can't access dead object的原因(pycharm中)

    PyCharm中运行firefox webdriver访问邮箱添加通讯录的时候报错-WebDriverException: Message: can't access dead object 调了半天 ...

  9. linux下高并发网络应用注意事项

    本文转自:http://www.blogjava.net/bacoo/archive/2012/06/11/380500.html linux下高并发网络应用注意事项 vi /etc/sysctl.c ...

  10. SharedObject对象聊天室

    本博推荐文章快速导航: Sql Server2005 Transact-SQL 新兵器学习MCAD学习 代码阅读总结 ASP.NET状态管理 DB(数据库)WAPWinFormFlex,Fms aie ...