题目描述

CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节。作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴。他很快就尝遍了美食节所有的美食。然而,尝鲜的欲望是难以满足的。尽管所有的菜品都很可口,厨师做菜的速度也很快,小M仍然觉得自己桌上没有已经摆在别人餐桌上的美食是一件无法忍受的事情。于是小M开始研究起了做菜顺序的问题,即安排一个做菜的顺序使得同学们的等待时间最短。小M发现,美食节共有n种不同的菜品。每次点餐,每个同学可以选择其中的一个菜品。总共有m个厨师来制作这些菜品。当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师。然后每个厨师就会同时开始做菜。厨师们会按照要求的顺序进行制作,并且每次只能制作一人份。此外,小M还发现了另一件有意思的事情: 虽然这m个厨师都会制作全部的n种菜品,但对于同一菜品,不同厨师的制作时间未必相同。他将菜品用1, 2, ..., n依次编号,厨师用1, 2, ..., m依次编号,将第j个厨师制作第i种菜品的时间记为 ti,j 。小M认为:每个同学的等待时间为所有厨师开始做菜起,到自己那份菜品完成为止的时间总长度。换句话说,如果一个同学点的菜是某个厨师做的第k道菜,则他的等待时间就是这个厨师制作前k道菜的时间之和。而总等待时间为所有同学的等待时间之和。现在,小M找到了所有同学的点菜信息: 有 pi 个同学点了第i种菜品(i=1, 2, ..., n)。他想知道的是最小的总等待时间是多少。

题解

一开始按照修车那题的思路搞了个费用流,就是把厨师拆成tim个点,表示他是倒数第几个做的,然后边权就是对后面的人的代价和,然后T到飞起。

原因是直接把图建出来导致图的规模过大,然后spfa就死了。

所以我们可以动态加边,每增广一次就加一个点。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<queue>
  5. #define N 49
  6. #define M 109
  7. #define P 809
  8. #define R register
  9. using namespace std;
  10. queue<int>q;
  11. int p[N],head[M*P],tot=,dis[M*P],pre[M*P],fl[M*P],ans,n,m,sum,a[N][M],tim[M*P],id[M],be[M*P];
  12. bool vis[M*P];
  13. inline int rd(){
  14. int x=;char c=getchar();bool f=;
  15. while(!isdigit(c)){if(c=='-')f=;c=getchar();}
  16. while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
  17. return f?-x:x;
  18. }
  19. struct edge{int n,to,l,f;}e[N*M*P*];
  20. inline void add(int u,int v,int l,int f){
  21. e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;e[tot].f=f;
  22. e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=;e[tot].f=-f;
  23. }
  24. inline bool spfa(int s,int t){
  25. memset(dis,0x3f,sizeof(dis));
  26. q.push(s);dis[s]=;fl[s]=2e9;
  27. while(!q.empty()){
  28. int u=q.front();q.pop();vis[u]=;
  29. // cout<<u<<" "<<dis[u]<<endl;
  30. for(R int i=head[u];i;i=e[i].n){
  31. int v=e[i].to;
  32. if(e[i].l&&dis[v]>dis[u]+e[i].f){
  33. dis[v]=dis[u]+e[i].f;pre[v]=i;fl[v]=min(fl[u],e[i].l);
  34. if(!vis[v]){vis[v]=;q.push(v);}
  35. }
  36. }
  37. }
  38. return dis[t]!=0x3f3f3f3f;
  39. }
  40. inline void calc(int s,int t){
  41. int x=t;
  42. while(x!=s){
  43. int i=pre[x];
  44. e[i].l-=fl[t];e[i^].l+=fl[t];x=e[i^].to;
  45. }
  46. ans+=dis[t]*fl[t];
  47. }
  48. int main(){
  49. n=rd();m=rd();
  50. for(R int i=;i<=n;++i)p[i]=rd(),sum+=p[i];
  51. for(R int i=;i<=n;++i)for(R int j=;j<=m;++j)a[i][j]=rd();
  52. int now=n;
  53. for(R int i=;i<=m;++i)for(R int j=;j<=sum;++j){
  54. ++now;tim[now]=j==?:tim[now-]+;if(j==)id[i]=now;be[now]=i;
  55. }
  56. for(R int i=;i<=n;++i)for(R int j=;j<=m;++j)add(i,id[j],,a[i][j]);
  57. for(R int i=;i<=m;++i)add(id[i],now+,,);
  58. for(R int i=;i<=n;++i)add(,i,p[i],);
  59. while(spfa(,now+)){
  60. calc(,now+);
  61. int x=e[pre[now+]^].to;x++;
  62. add(x,now+,,);
  63. for(int i=;i<=n;++i)add(i,x,,tim[x]*a[i][be[x]]);
  64. }
  65. cout<<ans;
  66. return ;
  67. }

[NOI2012]美食节(费用流)的更多相关文章

  1. [NOI2012]美食节——费用流(带权二分图匹配)+动态加边

    题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...

  2. 【bzoj2879】[Noi2012]美食节 费用流+动态加边

    原文地址:http://www.cnblogs.com/GXZlegend 题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他 ...

  3. BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )

    倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...

  4. [BZOJ2879][NOI2012]美食节(费用流)

    设sm为所有p之和,套路地对每道菜建一个点,将每个厨师拆成sm个点,做的倒数第i道菜的代价为time*i. S向每道菜连边<0,p[i]>(前者为代价后者为流量),i菜到j厨师的第k个点连 ...

  5. [BZOJ2879] [Noi2012] 美食节 (费用流 & 动态加边)

    Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...

  6. BZOJ.2879.[NOI2012]美食节(费用流SPFA)

    题目链接 /* 同"修车":对于每个厨师拆成p个点表示p个时间点,每个人向m个厨师每个时间点连边 这样边数O(nmp)+网络流 ≈O(nm*p^2)(假设SPFA线性) = GG ...

  7. 【BZOJ 2879】[Noi2012]美食节 费用流

    思路同修车,就是多了一个骚气的操作:动态加边,我们通过spfa流的过程可以知道,我们一次只会跑一流量,最后一层边跑过就不会再悔改,所以说我们只会用到一大片里面的很少的点,所以我们如果可以动态加边的话我 ...

  8. BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点

    这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...

  9. [NOI2012][bzoj2879] 美食节 [费用流+动态加边]

    题面 传送门 思路 先看看这道题 修车 仔细理解一下,这两道题是不是一样的? 这道题的不同之处 但是有一个区别:本题中每一种车有多个需求,但是这个好办,连边的时候容量涨成$p\lbrack i\rbr ...

随机推荐

  1. js 正则进阶regexp

    一.匹配中文,英文字母和数字及_: const reg = /^[\u4e00-\u9fa5\w]+$/; const str1 = 'shangyy'; const str2 = '尚悦悦ww123 ...

  2. The New Villa

    题目:The New Villa 题目链接:http://poj.org/problem?id=1137 题目大意: 一个人买了一个别墅,里面有很多房间,特别的是这个别墅的房间里灯的开关是乱套的,也就 ...

  3. 批量处理word所有回车行

    在WORD中点击CTRL+H,弹出对话框,输入如下替换符

  4. jquery选择基础

    1 元素选择器 之前不熟悉的是如: $("input.cls1"); 这种用法 2 属性选择器 包含name属性的input元素, 如 $("input[name]&qu ...

  5. List接口方法

    package cn.zhou.com; /* * List?-------是啥? Collection 的一个子接口! * * 集合?容器? * * 区分容器,每个容器的数据结构不一样! * 集合, ...

  6. thinkphp5 实现搜索分页能下一页保留搜索条件

    正常情况下: 搜索后分页了,点击第二页,进入页面之前的搜索条件没有了. 如代码 $keywords=$this->request->param('keywords'); $this-> ...

  7. js函数使用prototype和不适用prototype的区别

    js中类定义函数时用prototype与不用的区别 原创 2017年06月05日 12:25:41 标签: 函数 / prototype / class   首先来看一个实例: function Li ...

  8. Directory of X:\EFI\Microsoft\Boot

    Directory of X:\EFI\Microsoft\Boot 2017/06/21 15:14 <DIR> . 2017/06/21 15:14 <DIR> .. 20 ...

  9. 3.docker基础架构

    docker是一个典型的c/s架构产品. dockerd :为客户端提供  RESTFUL API,响应来自客户端的请求, 采用模块化的架构, 通过专门的 Engine 模块来分发管理各 个来自客户端 ...

  10. Span<T>

    Introduction Span<T> is a new type we are adding to the platform to represent contiguous regio ...