【题目】

传送门

题目描述:

CZ 市为了欢迎全国各地的同学,特地举办了一场盛大的美食节。

作为一个喜欢尝鲜的美食客,小 M 自然不愿意错过这场盛宴。他很快就尝遍了美食节所有的美食。然而,尝鲜的欲望是难以满足的。尽管所有的菜品都很可口,厨师做菜的速度也很快,小 M 仍然觉得自己桌上没有已经摆在别人餐桌上的美食是一件无法忍受的事情。于是小 M 开始研究起了做菜顺序的问题,即安排一个做菜的顺序使得同学们的等待时间最短。

小 M 发现,美食节共有 n n n 种不同的菜品。每次点餐,每个同学可以选择其中的一个菜品。总共有 m m m 个厨师来制作这些菜品。当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师。然后每个厨师就会同时开始做菜。厨师们会按照要求的顺序进行制作,并且每次只能制作一人份。

此外,小 M 还发现了另一件有意思的事情:虽然这 m m m 个厨师都会制作全部的 n n n 种菜品,但对于同一菜品,不同厨师的制作时间未必相同。他将菜品用 1 , 2 , . . . , n 1, 2, ..., n 1,2,...,n 依次编号,厨师用 1 , 2 , . . . , m 1,2,...,m 1,2,...,m 依次编号,将第 j j j 个厨师制作第 i i i 种菜品的时间记为 t i , j t_{i,j} ti,j​ 。

小 M 认为:每个同学的等待时间为所有厨师开始做菜起,到自己那份菜品完成为止的时间总长度。换句话说,如果一个同学点的菜是某个厨师做的第 k k k 道菜,则他的等待时间就是这个厨师制作前 k k k 道菜的时间之和。而总等待时间为所有同学的等待时间之和。

现在,小 M 找到了所有同学的点菜信息:有 p i p_i pi​ 个同学点了第 i i i 种菜品( i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n)。他想知道的是最小的总等待时间是多少。

输入格式:

输入文件的第 1 1 1 行包含两个正整数 n n n 和 m m m ,表示菜品的种数和厨师的数量。

第 2 2 2 行包含 n n n 个正整数,其中第 i i i 个数为 p i p_i pi​,表示点第 i i i 种菜品的人数。

接下来有 n n n 行,每行包含 m m m 个非负整数,这 n n n 行中的第 i i i 行的第 j j j 个数为 t i , j t_{i,j} ti,j​,表示第 j j j 个厨师制作第 i i i 种菜品所需的时间。

输入每行相邻的两个数之间均由一个空格隔开,行末均没有多余空格。

输出格式:

输出仅一行包含一个整数,为总等待时间的最小值。

样例数据:

输入
3 2
3 1 1
5 7
3 6
8 9

输出
47

备注:

【样例说明】

厨师 1 1 1 先制作 1 1 1 份菜品 2 2 2,再制作 2 2 2 份菜品 1 1 1。点这 3 3 3 道菜的 3 3 3 个同学的等待时间分别为 3 3 3, 3 + 5 = 8 3+5=8 3+5=8, 3 + 5 + 5 = 13 3+5+5=13 3+5+5=13。
厨师 2 2 2 先制作 1 1 1 份菜品 1 1 1,再制作 1 1 1 份菜品 3 3 3。点这 2 2 2 道菜的 2 2 2 个同学的等待时间分别为 7 7 7, 7 + 9 = 16 7+9=16 7+9=16。
总等待时间为 3 + 8 + 13 + 7 + 16 = 47 3+8+13+7+16=47 3+8+13+7+16=47。

虽然菜品 1 1 1 和菜品 3 3 3 由厨师 1 1 1 制作更快,如果这些菜品都由厨师 1 1 1 制作,总等待时间反而更长。如果按上述的做法,将 1 1 1 份菜品 1 1 1 和 1 1 1 份菜品 3 3 3 调整到厨师 2 2 2制作,这样厨师 2 2 2 不会闲着,总等待时间更短。
可以证明,没有更优的点餐方案。

【数据范围】

对于 100 % 100\% 100% 的数据, n ≤ 40 n\le40 n≤40, m ≤ 100 m\le100 m≤100, p ≤ 800 p\le800 p≤800, t i , j ≤ 1000 t_{i,j}\le1000 ti,j​≤1000(其中 p = ∑ p i p=∑pi p=∑pi,即点菜同学的总人数)。

每组数据的 n n n、 m m m 和 p p p 值如下:

【分析】

这道题跟修车那道题很像啊,但是有两个不同点:

  1. 每个菜品可以点多份,这个好办,直接改一下源点到每个菜品的边的容量以及菜品总数即可。
  2. 数据规模变大了,这时直接建之前的方法建图有超过 6 × 1 0 6 6\times 10^6 6×106条边,会 TLE 的,要想一下优化。

那么,我们就先连现在需要的边,暂时不需要的边就先不要连上。

那什么是 “ “ “暂时不需要的边呢 ” ” ”?

由于我们把每个厨师拆成了 s u m sum sum 个点( s u m sum sum 是菜品总数),现在用 ( i , j ) (i,j) (i,j) 表示厨师 i i i 做在倒数第 j j j 道菜的这个点。

对于厨师 i i i,如果 ( i , j ) (i,j) (i,j) 还没有被增广, ( i , j + 1 ) (i,j+1) (i,j+1) 也就不可能被被增广,因为 ( i , j ) (i,j) (i,j) 肯定比 ( i , j + 1 ) (i,j+1) (i,j+1) 更优。

所以我们动态加边

在起初,只加上源点到菜品的边、菜品到 ( i , 1 ) (i,1) (i,1) 的边、 ( i , 1 ) (i,1) (i,1) 到汇点的边。

在每次增广后,如果增广到了 ( i , j ) (i,j) (i,j),就把菜品向 ( i , j + 1 ) (i,j+1) (i,j+1) 的边以及 ( i , j + 1 ) (i,j+1) (i,j+1) 的边加上,表示 ( i , j + 1 ) (i,j+1) (i,j+1) 也可供选择了。

然后每次建边后跑最小费用流就可以了。

【代码】

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
#define M 6000005
#define inf (1ll<<31ll)-1
using namespace std;
int n,m,s,t,sum,ans,tot=1;
int v[M],w[M],nxt[M],cost[M];
int a[105][105],d[N],first[N],pre[N],flow[N];
bool vis[N];
int id(int i,int j){return (i-1)*sum+j+n;}
void add(int x,int y,int f,int c)
{nxt[++tot]=first[x];first[x]=tot,v[tot]=y,w[tot]=f,cost[tot]=c;
}
bool spfa(int s)
{int x,y,i;memset(d,0x3f,sizeof(d));memset(pre,-1,sizeof(pre));memset(flow,0,sizeof(flow));memset(vis,false,sizeof(vis));queue<int>q;q.push(s);d[s]=0,flow[s]=inf;while(!q.empty()){x=q.front();vis[x]=false;q.pop();for(i=first[x];i;i=nxt[i]){y=v[i];if(w[i]&&d[y]>d[x]+cost[i]){d[y]=d[x]+cost[i];pre[y]=i,flow[y]=min(flow[x],w[i]);if(!vis[y])  q.push(y),vis[y]=true;}}}return d[t]!=0x3f3f3f3f;
}
void dinic()
{int u,i;while(spfa(s)){for(i=t;~pre[i];i=v[pre[i]^1]){w[pre[i]]-=flow[t],w[pre[i]^1]+=flow[t];ans+=flow[t]*cost[pre[i]];}u=v[pre[t]^1];add(u+1,t,1,0),add(t,u+1,0,0);int y=(u-n)%sum,x=(u-n-y)/sum+1;for(i=1;i<=n;++i)  add(i,u+1,1,a[i][x]*(y+1)),add(u+1,i,0,-a[i][x]*(y+1));}
}
int main()
{int i,j,x;scanf("%d%d",&n,&m);for(i=1;i<=n;++i){scanf("%d",&x),sum+=x;add(s,i,x,0),add(i,s,0,0);}s=0,t=n+m*sum+1;for(i=1;i<=m;++i)  add(id(i,1),t,1,0),add(t,id(i,1),0,0);for(i=1;i<=n;++i){for(j=1;j<=m;++j){scanf("%d",&a[i][j]);add(i,id(j,1),1,a[i][j]),add(id(j,1),i,0,-a[i][j]);}}while(spfa(s))  dinic();printf("%d",ans);return 0;
}

【NOI 2012】美食节相关推荐

  1. 高等数学(拉格朗日乘子法):NOI 2012 骑行川藏

    [NOI2012] 骑行川藏 输入文件:bicycling.in   输出文件:bicycling.out   评测插件 时间限制:1 s   内存限制:128 MB NOI2012 Day1 Des ...

  2. 姚班学霸陈立杰:16岁保送清华,18岁拿下IOI世界冠军,现摘得FOCS 2019最佳学生论文...

    郭一璞 安妮 发自 凹非寺 量子位 出品  | 公众号 QbitAI 今年的理论计算机顶会FOCS,一位来自浙江湖州的小哥哥一口气中了3篇论文,还拿下了最佳学生论文奖. 而且这不是偶然神迹,类似操作, ...

  3. python长沙_长沙python

    本文转自量子位(ID:QbitAI) 边策 鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 只用99行代码,你也可以像<冰雪奇缘>里的艾莎公主一样拥有冰雪魔法. 虽然你不能在现 ...

  4. 【数论Day1】 最大公约数(gcd)题目

    20170529-3数论_gcd 题解: http://www.cnblogs.com/ljc20020730/p/6919116.html 日期 序号 题目名称 输入文件名 输出文件名 时限 内存 ...

  5. 2020年的数据工程

    重点 (Top highlight) It is incredible how fast data processing tools and technologies are evolving. An ...

  6. 集成电路:芯片时代的到来

    研制历程 1952年,实用的晶体管问世不久,电子行业还盛行电子管之时,一家为石油行业提供地震勘探服务的公司以极其长远的眼光向贝尔实验室买下了专利许可,并斥资数百万美元押注晶体管市场,而它当时的年利润仅 ...

  7. 清华姚班毕业生开发新特效编程语言,99 行代码实现《冰雪奇缘》,网友:大神碉堡!创世的快乐...

    公众号关注 "GitHubDaily" 设为 "星标",每天带你逛 GitHub! 转自量子位,作者边策.鱼羊 只用 99 行代码,你也可以像<冰雪奇缘& ...

  8. 姚班大神胡渊鸣回国创业!超一半员工为清华校友,团队人均竞赛金牌数≥2

    本文经AI新媒体量子位(ID:QbitAI)授权转载,转载请联系出处 杨净 边策 发自 凹非寺 清华姚班出身的"计算机图形学超级新星"胡渊鸣同学回国创业啦! 胡渊鸣,何许人也? 他 ...

  9. 大神碉堡!99 行代码实现的神奇效果

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 边策 鱼羊 发自 凹非寺量子位 报道 | 公众号 QbitAI 只用99行代码,你也可以像<冰雪奇缘>里的 ...

最新文章

  1. IROS2021|DLL直接点云定位:一种基于点云地图的航空机器人定位方法
  2. 三、Flask_会话控制与请求钩子
  3. php功能与特性,PHP 6将实现的8个特性和功能
  4. java 判断一个数字是2倍数_如何判断语言发育迟缓的原因|一个2岁半不会说话的案例...
  5. 以太坊知识教程------智能合约(1)基本概念
  6. wikipedia_教职员工可以通过Wikipedia进行教学吗?
  7. Java使用HtmlUnit抓取js渲染页面
  8. 有人滥用 GitHub Actions在 GitHub 服务器挖掘密币,且正在蔓延
  9. NB-LOT 常用AT指令集简介
  10. cruzer php sandisk 闪迪u盘量产工具_闪迪sandisk U盘不量产修复方法教程
  11. esp8266网页控制RGB灯颜色
  12. SQL:查询各科成绩前三名
  13. 关于private继承
  14. 快速成为脚本小子_什么是脚本小子? 如何成为脚本小子?
  15. 抖音扫码跳转QQ群等外链源代码分享
  16. 安卓手机APP进行自动化点击软件详解
  17. origin画图修改横坐标
  18. canvas流星雨 数据流
  19. 南卡NEO骨传导首发新机,超前无线充设计,树立行业标杆!!!
  20. iOS 设置按钮上图下文的方式

热门文章

  1. python代码的注释贿一种方式、那就是使用井符号号_Python 代码的注释只有一种方式,那就是使用 # 符号。 (2.0分)_学小易找答案...
  2. 21华中师范大学874 人工智能教育学部上岸分享
  3. setfill(' ')的解释
  4. 醒醒神,爱奇艺笔试真题
  5. 程序员35岁之后的出路
  6. Windows 系统快速打开计算器
  7. XMODEM设计与C代码实现(1.整体设计篇)
  8. 【数据结构与算法】03 链表(基础知识+面试高频leetcode题目)
  9. http状态码之304
  10. Django中的反向查找