【BZOJ】2879: [Noi2012]美食节
题意
\(m\)个厨师,\(n\)种菜,每种菜需要做\(p_i\)份,每个厨师做第\(i\)种菜用时\(t_{i, j}\)。一个厨师做完一道菜才能做下一道。每份菜的时间是这个厨师做完这道菜的用时加上之前做过的菜的用时。问做完所有的菜的最小用时是多少。($ n \le 40, m \le 100, \sum p_i \le 800, t_{i, j} \le 1000 $)
分析
可以考虑每个厨师做的每一道菜。最后做的菜对时间贡献了一次,倒数第二的菜对时间贡献了两次。于是我们考虑每个厨师倒着做的菜品即可。
题解
将每个厨师拆成\(\sum p_i\)个点,表示这个菜是倒数第\(i\)次做的。但是这样一次性把图建出来会tle。所以我们要优化。
考虑到每个厨师倒数第一个菜一定在倒数第二个菜先做,所以我们按照这个顺序来建图即可,即增广一次建一次。
具体做法是:
首先加入\(m\)个点,表示每个厨师倒数第一次做的菜。源\(S\)向这些点连边,容量\(1\),费用为\(0\)。再加入\(n\)个点,表示菜类,每个点向汇连边,容量为\(p_i\),费用为\(0\)。然后在厨师的点集中向菜类点集连边,容量为\(1\),费用为\(t_{i, j}\)。
然后增广一条路径。此时找出被增广的厨师,再新建一个点,表示这个厨师第二次做的菜。源\(S\)向这个点连边,容量为\(1\),费用为\(0\)。然后向菜类连边,容量为\(1\),费用为\(2 t_{i, j}\)。依次类推。
#include <bits/stdc++.h>
using namespace std;
const int N=45, M=105, nN=N+M+1000, nE=N*(M+800)*8, oo=0x3f3f3f3f;
int ihead[nN], cnt=1;
struct E {
int next, from, to, cap, w;
}e[nE];
void add(int x, int y, int cap, int w) {
e[++cnt]=(E){ihead[x], x, y, cap, w}; ihead[x]=cnt;
e[++cnt]=(E){ihead[y], y, x, 0, -w}; ihead[y]=cnt;
}
bool spfa(int s, int t, int n, int &ans) {
static int d[nN], q[nN], p[nN], fr, ta;
static bool vis[nN];
memset(d, 0x3f, sizeof(int)*(n+1));
fr=ta=0;
d[s]=0;
q[ta++]=s;
while(fr!=ta) {
int x=q[fr++];
fr=fr==nN?0:fr;
vis[x]=0;
for(int i=ihead[x]; i; i=e[i].next) {
if(!e[i].cap) {
continue;
}
int y=e[i].to;
if(d[y]>d[x]+e[i].w) {
d[y]=d[x]+e[i].w;
p[y]=i;
if(!vis[y]) {
vis[y]=1;
q[ta++]=y;
ta=ta==nN?0:ta;
}
}
}
}
if(d[t]==oo) {
return 0;
}
for(int x=t; x!=s; x=e[p[x]].from) e[p[x]].cap--, e[p[x]^1].cap++;
ans+=d[t];
return 1;
}
int n, m, p[N], sum, pos[M], num[M], t[N][M], nu[N];
int main() {
int ans=0;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; ++i) {
scanf("%d", &p[i]);
sum+=p[i];
}
int S=n+m+sum+1, T=S+1;
for(int i=1; i<=n; ++i) {
add(S, i, p[i], 0);
for(int j=1; j<=m; ++j) {
scanf("%d", &t[i][j]);
}
}
for(int j=1; j<=m; ++j) {
int id=n+j;
add(id, T, 1, 0);
num[j]=1;
pos[j]=cnt;
for(int i=1; i<=n; ++i) {
add(i, id, 1, t[i][j]);
}
}
int tot=n+m;
while(spfa(S, T, T, ans)) {
int j=0;
for(j=1; j<=m && !e[pos[j]].cap; ++j);
++num[j];
++tot;
add(tot, T, 1, 0);
pos[j]=cnt;
for(int i=1; i<=n; ++i) {
add(i, tot, 1, num[j]*t[i][j]);
}
}
printf("%d\n", ans);
return 0;
}
【BZOJ】2879: [Noi2012]美食节的更多相关文章
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- BZOJ 2879: [Noi2012]美食节 最小费用流 动态添边
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 324 Solved: 179[Submit][Status] ...
- BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )
倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...
- BZOJ 2879 NOI2012美食节
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2879 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M ...
- BZOJ.2879.[NOI2012]美食节(费用流SPFA)
题目链接 /* 同"修车":对于每个厨师拆成p个点表示p个时间点,每个人向m个厨师每个时间点连边 这样边数O(nmp)+网络流 ≈O(nm*p^2)(假设SPFA线性) = GG ...
- BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点
这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...
- 2879: [Noi2012]美食节 - BZOJ
Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...
- 2879: [Noi2012]美食节
Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...
- 2879. [NOI2012]美食节【费用流】
Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...
随机推荐
- Redis笔记(八)Redis的持久化
Redis相比Memcached的很大一个优势是支持数据的持久化, 通常持久化的场景一个是做数据库使用,另一个是Redis在做缓存服务器时,防止缓存失效. Redis的持久化主要有快照Snapshot ...
- 通过url获取图片尺寸的几种方法:JS和php
首先是js的方法,通过new一个Image对象,设置src属性,并监听complete和onload事件,图片加载完成后输出图片的宽度和高度 function checkPicurl(url){ va ...
- JSON C# Class Generator ---由json字符串生成C#实体类的工具(转)
转载地址:http://www.cnblogs.com/finesite/archive/2011/07/31/2122984.html json作为互联网上轻量便捷的数据传输格式,越来越受到重视.但 ...
- ckplayer视频播放插件使用
研究ckplayer插件播放视频,播放视频需要配置信息修改如下: 1.设置ckplayer.js中的logo: 'null' 可以隐藏视频播放头部的图标: 2.设置ckplayer.js中的ckcpt ...
- How many Fibs?【sudt 2321】【大数的加法及其比较】
How many Fibs? Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Recall the definition of t ...
- SQL Server创建随机测试数据
我们在做数据仓库开发的过程中,经常需要插入大量的测试数据来测试数据库查询性能和计算占用的存储空间等.本文主要介绍下不借用第三方的工具在数据库中直接生成大量的测试数据. 需求 每一行包含5个日期字段和一 ...
- hdu 4034 2011成都赛区网络赛 逆向floyd **
给出一个最短路邻接矩阵,求出构图的最小边数 正常的floyd的k放在最外面是为了防止i到j的距离被提前确定,而逆向的floyd,i到j的距离已经确定,所以需要在i到j之间枚举k,注意需要break,否 ...
- 背景虚化 Google Camera App Nokia Refocus HTC One M8 的 Duo景深相机
背景虚化是单反中一种比较常见的拍照形式,参看 http://www.techbang.com/posts/%2017842 https://refocus.nokia.com/
- 数据分析(4):Scipy
科学计算 最小二乘leastsq # -*- coding: utf-8 -*- def func(x,p): # p 参数列表 A,k,theta = p; # 可以一一对应赋值 return A* ...
- Windows7系统主题制作全程教程
jpg 改 rar