zoukankan      html  css  js  c++  java
  • JZOJ 1259. 牛棚安排

    题目

    Description

    Farmer John的N(1<=N<=1000)头奶牛分别居住在农场所拥有的B(1<=B<=20)个牛棚的某一个里。有些奶牛很喜欢她们当前住的牛棚,而另一些则讨厌再在它们现在所在的牛棚呆下去。
    FJ在忍受了若干次奶牛的抱怨后,决定为所有奶牛重新安排牛棚,使最不满的那头奶牛与最高兴的奶牛的心情差异最小,即使这会让所有奶牛都更加郁闷。
    每头奶牛都把她对各个牛棚的好感度从高到低排序后告诉了FJ。当然,如果一头奶牛被安排到的牛棚在她给出的列表中越靠后,她就会越郁闷。你可以认为奶牛的郁闷指数是她被分配到的牛棚在列表中的位置。奶牛们是斤斤计较的,她们无法容忍别的奶牛在自己喜欢的牛棚里快乐地生活,而自己却呆在一个自己不喜欢的牛棚里。每个牛棚都只能容纳一定数量的奶牛。FJ希望在每个牛棚都没有超出容量限制的前提下,使最郁闷和最高兴的奶牛的郁闷指数的跨度最小。 
    FJ请你帮他写个程序,来计算这个最小的郁闷指数跨度到底是多少。
     

    Input

    第1行: 包含2个用空格隔开的整数N和B,分别表示牛和牛棚的数量
    第2..N+1行: 每行包含B个用空格隔开的整数,刚好完全包含1..B的整数。第i+1行的第一个整数,表示奶牛i最喜欢的牛棚编号。第二个整数表示奶牛i的列表中排在第二位,也就是她第二喜欢的牛棚。依此类推。
    第N+2行: 包含B个用空格隔开的整数,第i个整数表示牛棚i最多能容纳的奶牛的数目。所有牛棚能容纳奶牛头数的和至少是N。 

    Output

    第1行: 输出一个整数,表示所有奶牛中最高兴与最郁闷的牛的郁闷指数跨度
     

    Sample Input

    6 4
    1 2 3 4
    2 3 1 4
    4 2 3 1
    3 1 2 4
    1 3 4 2
    1 4 2 3
    2 1 3 2
    

    Sample Output

    2
     

    Data Constraint

     
     

    Hint

    【样例说明】
    每头奶牛都能被安排进她的第一或第二喜欢的牛棚。下面给出一种合理的分配方案:奶牛1和奶牛5住入牛棚1,牛棚2由奶牛2独占,奶牛4住进牛棚3,剩下的奶牛3和奶牛6安排到牛棚4。

     

    分析

     

    二分答案加网络流

    我边上加多一个忧郁值,如果我忧郁值大于当前枚举就不能流

     

    代码

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 #include<cstdio> 
     5 using namespace std;
     6 const int N=1e3+10;
     7 const int B=21;
     8 const int inf=2147483647;
     9 int s,t,l;
    10 int n,b,ans;
    11 int cnt=1,mid;
    12 int a[10001];
    13 int dis[10001];
    14 int list[110001];
    15 struct node {
    16     int u,v,c,w,nx;
    17 }g[2*N*B+2*N+2*B];
    18 void add(int u,int v,int w,int c) {
    19     g[++cnt]=(node){u,v,c,w,list[u]};list[u]=cnt;
    20     g[++cnt]=(node){v,u,0,0,list[v]};list[v]=cnt;
    21 }
    22 bool bfs()
    23 {
    24     queue<int> q;
    25     while(!q.empty()) q.pop();
    26     memset(dis,0,sizeof(dis));
    27     q.push(s);
    28     dis[s]=1;
    29     while (!q.empty())
    30     {
    31         int x=q.front(); q.pop();
    32         for (int i=list[x];i;i=g[i].nx)
    33         {
    34             int y=g[i].v;
    35             if (g[i].c&&!dis[y]&&(l<=g[i].w&&g[i].w<=l+mid-1||g[i].w==0))
    36             {
    37                 dis[y]=dis[x]+1;
    38                 if (y==t) return 1;
    39                 q.push(y); 
    40             }
    41         }
    42     }
    43     return 0;
    44 }
    45 int dfs(int x,int maxf)
    46 {
    47     if (x==t) return maxf;
    48     int ret=0;
    49     for (int i=list[x];i;i=g[i].nx)
    50     {
    51         int y=g[i].v;
    52         if (g[i].c&&dis[y]==dis[x]+1&&(l<=g[i].w&&g[i].w<=l+mid-1||g[i].w==0))
    53         {
    54             int f=dfs(y,min(g[i].c,maxf-ret));
    55             if (!f) dis[y]=-1;
    56             g[i].c-=f;
    57             g[i^1].c+=f;
    58             ret+=f;
    59             if (ret==maxf) return ret; 
    60         } 
    61     }
    62     return ret;
    63 }
    64 bool dinic()
    65 {
    66     int flow;
    67     for (l=1;l<=max(1,b-mid+1);l++)
    68     {
    69         flow=0;
    70         while (bfs())
    71            flow+=dfs(s,inf);
    72         for (int i=2;i<=cnt;i+=2)
    73            if (g[i].u==s) g[i].c=a[g[i].v],g[i^1].c=0;
    74            else g[i].c=1,g[i^1].c=0;
    75         if (flow==n) return 1;
    76     }
    77     return 0;
    78 }
    79 int main ()
    80 {
    81     cin>>n>>b;
    82     s=0,t=n+b+1;
    83     for (int i=1;i<=n;i++)
    84        for (int j=1,c;j<=b;j++)
    85        {
    86              cin>>c;
    87              add(c,i+b,j,1);
    88        }
    89     for (int i=1;i<=b;i++) scanf("%d",&a[i]),add(s,i,0,a[i]);
    90     for (int i=1;i<=n;i++) add(i+b,t,0,1);
    91     int l=1,r=20;
    92     while (l<=r)
    93     {
    94         mid=l+r>>1;
    95         if (dinic()) ans=mid,r=mid-1;
    96         else l=mid+1; 
    97     }
    98     cout<<ans; 
    99 }

     

    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    android listview 的弹性滑动 简单demo 实现
    android轻松监听来电和去电
    android有效的获取图像和视频
    android项目源码异步加载远程图片的小例子
    Android游戏开发系统控件CheckBox
    Android Gallery3D效果 教程 案例 代码
    Android 桌面组件【app widget】 进阶项目心情记录器
    基于ListView和CheckBox实现多选和全选记录的功能
    Android上传文件到服务器中的简单实例
    最小边覆盖(最小路径覆盖)(路径可相交)——pku2594
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11135109.html
Copyright © 2011-2022 走看看