• Jamie's Contact Groups


    poj2289:http://poj.org/problem?id=2289

    题意:给定一个规模为n的名单,要将名单中的人归到m个组中,给出每个人可能的分组号,需要确定一种分配方案,是的最大规模的组最小。

    题解:很明显的二分。然后把人和组都拆点即可。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<queue>
      6 #define INF 100000000
      7 using namespace std;
      8 const int N=3205;
      9 const int M=1000000;
     10 struct Node{
     11    int v;
     12    int f;
     13    int next;
     14 }edge[M];
     15 int n,m,u,v,cnt,sx,ex;
     16 int head[N],pre[N];
     17 int val[N][40];//根据题目要求申请
     18 void init(){
     19     cnt=0;
     20     memset(head,-1,sizeof(head));
     21 }
     22 void add(int u,int v,int w){
     23     edge[cnt].v=v;
     24     edge[cnt].f=w;
     25     edge[cnt].next=head[u];
     26     head[u]=cnt++;
     27     edge[cnt].f=0;
     28     edge[cnt].v=u;
     29     edge[cnt].next=head[v];
     30     head[v]=cnt++;
     31 }
     32 bool BFS(){
     33   memset(pre,0,sizeof(pre));
     34   pre[sx]=1;
     35   queue<int>Q;
     36   Q.push(sx);
     37  while(!Q.empty()){
     38      int d=Q.front();
     39      Q.pop();
     40      for(int i=head[d];i!=-1;i=edge[i].next    ){
     41         if(edge[i].f&&!pre[edge[i].v]){
     42             pre[edge[i].v]=pre[d]+1;
     43             Q.push(edge[i].v);
     44         }
     45      }
     46   }
     47  return pre[ex]>0;
     48 }
     49 int dinic(int flow,int ps){
     50     int f=flow;
     51      if(ps==ex)return f;
     52      for(int i=head[ps];i!=-1;i=edge[i].next){
     53         if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
     54             int a=edge[i].f;
     55             int t=dinic(min(a,flow),edge[i].v);
     56               edge[i].f-=t;
     57               edge[i^1].f+=t;
     58             flow-=t;
     59              if(flow<=0)break;
     60         }
     61 
     62      }
     63       if(f-flow<=0)pre[ps]=-1;
     64       return f-flow;
     65 }
     66 int solve(){
     67     int sum=0;
     68     while(BFS())
     69         sum+=dinic(INF,sx);
     70     return sum;
     71 }
     72 char str[20];
     73 int ans[N][N];
     74 int tot[N],top;
     75 void build(int mid){
     76      init();
     77      for(int i=1;i<=n;i++){
     78         for(int j=1;j<=tot[i];j++){
     79             add(i+n,ans[i][j]+2*n,1);
     80         }
     81         add(i,i+n,1);
     82         add(0,i,1);
     83      }
     84      for(int i=1;i<=m;i++){
     85         add(i+2*n,i+2*n+m,mid);
     86         add(i+2*n+m,2*m+2*n+1,INF);
     87      }
     88 }
     89 int as,temp;
     90 int main() {
     91     while(~scanf("%d%d",&n,&m)&&n) {
     92          init();
     93          as=0;
     94        for(int i=1;i<=n;i++){
     95           scanf("%s",str);
     96           top=0;
     97           while(getchar()!='
    '){
     98               scanf("%d",&temp);
     99               //printf("**%d
    ",temp);
    100               ans[i][++top]=++temp;
    101           }
    102             tot[i]=top;
    103        }
    104        int l=0,r=n;
    105        sx=0,ex=2*n+2*m+1;
    106        while(l<=r){
    107           int mid=(l+r)/2;
    108           build(mid);
    109           if(solve()==n){
    110             r=mid-1;
    111             as=mid;
    112           }
    113           else
    114             l=mid+1;
    115        }
    116     printf("%d
    ",as);
    117 
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    17年day4
    11.7NOIP模拟题
    P3389 【模板】高斯消元法
    洛谷 P2136 拉近距离 题解
    浅谈SPFA判负环
    洛谷 P1629 邮递员送信 题解
    洛谷 P1821 [USACO07FEB]银牛派对Silver Cow Party 题解
    洛谷 P3905 道路重建 题解
    洛谷 P1351 联合权值 题解
    洛谷 P4779 【模板】单源最短路径(标准版) 题解
  • 原文地址:https://www.cnblogs.com/chujian123/p/3948576.html
Copyright © 2020-2023  润新知