poj 2289 Jamie's Contact Groups(二分答案+网络流判定)
来源:互联网 发布:js获取当前页面html 编辑:程序博客网 时间:2024/04/28 13:28
【题目大意】:n个人,告诉你他可以从属于那些小组,现在问你将n个人分成m组,最大的组最小的人数是多少。
【解题思路】:最大最小值...想到的是二分出上界,符合条件则缩小上界,反之则增大。如何判断,可以用网络流来判定,构图是由s出发,连边到人容量为1,每个人和小组之间的对应关系连边,容量为1,小组和汇点t连边,容量为二分出来的上界...然后跑一个网络流判断汇点是否是n就可以了....
热身赛,队友不在,不会图论,硬着头皮扛,-_-!!....用的还是队友的模版......除掉模版之后...没了....
【代码】:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip> using namespace std; #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define linf 1LL<<60#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long long#define maxn 2000#define maxm 1000000struct per{ int st[600],cnt;}per[2000];int s,t;int n,m;int dist[maxn],low[maxn],tot,eh[maxn],pre[maxn],cnt[maxn],cur[maxn];int maz[maxn][maxn],mapp[maxn][maxn]; struct Edge { int u,v,cap,flow,next;}et[maxm]; void init() { tot=0; memset(eh,-1,sizeof(eh));} void add(int u,int v,int cap,int flow) { Edge E={u,v,cap,flow,eh[u]}; et[tot]=E; eh[u]=tot++;} void addedge(int u,int v,int cap) { add(u,v,cap,0),add(v,u,0,0);} int isap(int s,int t,int n) { int u,v,now; memset(dist,0,sizeof(dist)); memset(low,0,sizeof(low)); for (u=0; u<=n; u++) cur[u]=eh[u]; int maxflow=0; u=s; low[s]=inf,cnt[0]=n; while (dist[s]<n) { for (now=cur[u]; now!=-1; now=et[now].next) if (et[now].cap-et[now].flow && dist[u]==dist[v=et[now].v]+1) break; if (now!=-1) { cur[u]=pre[v]=now; low[v]=min(low[u],et[now].cap-et[now].flow); u=v; if (u==t) { for (; u!=s; u=et[pre[u]].u) { et[pre[u]].flow+=low[t]; et[pre[u]^1].flow-=low[t]; } low[s]=inf; maxflow+=low[t]; } } else { if (--cnt[dist[u]]==0) break; dist[u]=n; cur[u]=eh[u]; for (now=eh[u]; now!=-1; now=et[now].next) if (et[now].cap-et[now].flow && dist[u]>dist[et[now].v]+1) dist[u]=dist[et[now].v]+1; cnt[dist[u]]++; if(u!=s) u=et[pre[u]].u; } } return maxflow; }bool check(int cap) { s=0; t=n+m+1; init(); for (int i=1; i<=n; i++) { addedge(s,i,1); for (int j=0; j<per[i].cnt; j++) addedge(i,per[i].st[j]+n+1,1); } for (int i=1; i<=m; i++) addedge(i+n,t,cap); if (isap(s,t,t-s+1)==n) return true; else return false;} int main(){ char ch; string name; while(~scanf("%d%d",&n,&m)){ if (n==0 && m==0) break; for (int i=1; i<=n; i++) { cin >> name; per[i].cnt=0; ch=getchar(); while (ch!='\n'){ scanf("%d",&per[i].st[per[i].cnt]); per[i].cnt++; ch=getchar(); } } int l=1,r=n,ans=-1; while (l<=r) { int mid=(l+r)/2; if (check(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",ans); } return 0;}
- poj 2289 Jamie's Contact Groups(二分答案+网络流判定)
- poj 2289 Jamie's Contact Groups 二分+网络流
- 【POJ 2289】 Jamie's Contact Groups 【网络流+二分】
- POJ 2289 Jamie's Contact Groups (二分+匹配/网络流)
- poj2289 Jamie's Contact Groups(二分答案+最大流)
- POJ 2289 - Jamie's Contact Groups 二分+最大流
- POJ 2289 Jamie's Contact Groups(二分+最大流)
- poj 2289 Jamie's Contact Groups 【二分 + 最大流】
- poj 2289 Jamie's Contact Groups【二分 + 最大流】
- POJ 2289 Jamie's Contact Groups(二分+最大流)
- Poj 2289 Jamie's Contact Groups 【最大流Dinic+二分】
- poj 2289 Jamie's Contact Groups(二分+多重匹配)
- POJ 2289 Jamie's Contact Groups (二分答案+二分图的多重匹配)
- POJ--2289--Jamie's Contact Groups【二分图多重匹配+二分答案】
- POJ 2289 Jamie's Contact Groups 多重匹配+二分
- POJ 2289 Jamie's Contact Groups (二分+dinic)
- poj 2289 Jamie's Contact Groups 二分图多重匹配
- POJ 2289 Jamie's Contact Groups 二分+最大匹配
- KMP算法之来龙去脉
- 学习
- stm32中断向量表初探
- 【redhat5.5】Bootloader 的密码设置
- 图像处理_二值化
- poj 2289 Jamie's Contact Groups(二分答案+网络流判定)
- 林恩网开通
- Ipad2 home键失灵的解决方法
- javascript面向对象精华编程(转)
- [android]使用线控耳机来操控应用功能
- 集合类Collections
- D3D编程之网格文件
- 微软笔试题
- WinXP 无线提示“区域中找不到无线网络”的一种可能原因!