Description

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)。他想知道的是最小的总等待时间是多少。

Input

输入文件的第1行包含两个正整数n和m,表示菜品的种数和厨师的数量。 第2行包含n个正整数,其中第i个数为pi,表示点第i种菜品的人数。 接下来有n行,每行包含m个非负整数,这n行中的第i行的第j个数为ti,j,表示第j个厨师制作第i种菜品所需的时间。 输入文件中每行相邻的两个数之间均由一个空格隔开,行末均没有多余空格。
Output

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

3 2
3 1 1
5 7
3 6
8 9
Sample Output

47

【样例说明】
厨师1先制作1份菜品2,再制作2份菜品1。点这3道菜的3个同学的等待时间分别为3,3+5=8,3+5+5=13。
厨师2先制作1份菜品1,再制作1份菜品3。点这2道菜的2个同学的等待时间分别为7,7+9=16。
总等待时间为3+8+13+7+16=47。
虽然菜品1和菜品3由厨师1制作更快,如果这些菜品都由厨师1制作,总等待时间反而更长。如果按上述的做法,将1份菜品1和1份菜品3调整到厨师2制作,这样厨师2不会闲着,总等待时间更短。
可以证明,没有更优的点餐方案。

【数据规模及约定】
对于100%的数据,n <= 40, m <= 100, p <= 800, ti,j <= 1000(其中p = ∑pi,即点菜同学的总人数)。
每组数据的n、m和p值如下:
测试点编号 n m p
1 n = 5 m = 5 p = 10
2 n = 40 m = 1 p = 400
3 n = 40 m = 2 p = 300
4 n = 40 m = 40 p = 40
5 n = 5 m = 40 p = 100
6 n = 10 m = 50 p = 200
7 n = 20 m = 60 p = 400
8 n = 40 m = 80 p = 600
9 n = 40 m = 100 p = 800
10 n = 40 m = 100 p = 800

费用流很明显啦,把做菜的顺序倒过来,那么第一个人做的第一个菜贡献是一倍,第二个菜的贡献是两倍,依此类推

但是为了省时,所以动态加边,当一个人的第k个菜做好了,我们就加一个点,表示他做第k+1个菜

 const
maxn=;
maxm=;
maxd=;
maxe=;
var
a:array[..maxn,..maxm]of longint;
t:array[..maxn]of longint;
flag:array[..maxd]of boolean;
first,who,q,dis,pre:array[..maxd]of longint;
last,next,w,liu:array[..maxe]of longint;
n,m,tot,cnt,sum,ans,l,r:longint; procedure insert(x,y,ww,l:longint);
begin
inc(tot);
last[tot]:=y;
next[tot]:=first[x];
first[x]:=tot;
w[tot]:=ww;liu[tot]:=l;
end; procedure spfa;
var
i:longint;
begin
l:=;r:=;q[]:=;dis[]:=;
for i:= to cnt do dis[i]:=maxlongint;
for i:= to cnt do flag[i]:=false;
flag[maxd]:=false;
flag[]:=true;
dis[maxd]:=maxlongint;
while l<>r do
begin
i:=first[q[l]];
while i<> do
begin
if (liu[i]>) and (dis[q[l]]+w[i]<dis[last[i]]) then
begin
if flag[last[i]]=false then
begin
q[r]:=last[i];r:=(r+) mod maxd;
flag[last[i]]:=true;
end;
dis[last[i]]:=dis[q[l]]+w[i];pre[last[i]]:=i;
end;
i:=next[i];
end;
flag[q[l]]:=false;l:=(l+)mod maxd;
end;
inc(ans,dis[maxd]);
i:=maxd;
while i<> do
begin
dec(liu[pre[i]]);inc(liu[pre[i]xor ]);
i:=last[pre[i]xor ];
end;
i:=maxd;
while last[pre[i]xor ]<> do
i:=last[pre[i]xor ];
inc(cnt);
who[cnt]:=who[i];
inc(t[who[cnt]]);
insert(,cnt,,);insert(cnt,,,);
for i:= to m do
begin
insert(cnt,n+i,a[who[cnt],i]*t[who[cnt]],);
insert(n+i,cnt,-a[who[cnt],i]*t[who[cnt]],);
end;
end; procedure main;
var
i,j,x:longint;
begin
read(m,n);
tot:=;
cnt:=n+m;
for i:= to m do
begin
read(x);inc(sum,x);
insert(n+i,maxd,,x);
insert(maxd,n+i,,);
end;
for i:= to m do
for j:= to n do
read(a[j,i]);
for i:= to n do
begin
insert(,i,,);
insert(i,,,);
t[i]:=;who[i]:=i;
end;
for i:= to n do
for j:= to m do
begin
insert(i,n+j,a[i,j],);
insert(n+j,i,-a[i,j],);
end;
for i:= to sum do
spfa;
writeln(ans);
end; begin
main;
end.

2879: [Noi2012]美食节 - BZOJ的更多相关文章

  1. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  2. BZOJ 2879: [Noi2012]美食节 最小费用流 动态添边

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 324  Solved: 179[Submit][Status] ...

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

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

  4. BZOJ 2879 NOI2012美食节

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2879 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M ...

  5. 【BZOJ】2879: [Noi2012]美食节

    题意 \(m\)个厨师,\(n\)种菜,每种菜需要做\(p_i\)份,每个厨师做第\(i\)种菜用时\(t_{i, j}\).一个厨师做完一道菜才能做下一道.每份菜的时间是这个厨师做完这道菜的用时加上 ...

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

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

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

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

  8. 2879: [Noi2012]美食节

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

  9. 2879. [NOI2012]美食节【费用流】

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

随机推荐

  1. server——小记

    问题 Step 1   Start the server in Directory Services Restore Mode   Windows Server 2003/2008 Directory ...

  2. 防止服务器被暴力破解使用DenyHosts

    公司有台服务器被坏人盯上了,通过日志可以看到一直在做暴力破解ssh. 防止服务器被暴力破解使用DenyHosts 参考链接: 防止ssh破解,Ubuntu安装denyhosts的一些问题 防止你的ss ...

  3. Swift字符串类型

    字符串初始化 1.初始化 let  someString        =   "Some      string    literalvalue" let wiseWords = ...

  4. 20141212--C#对象比较

    static void Main(string[] args) { Class2 oo = new Class2(); oo.shu = ; oo.zi = "你"; Class2 ...

  5. How Do I Declare A Block in Objective-C?

    As a local variable: returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...}; As a p ...

  6. Codevs 1083 Cantor表

     时间限制: 1 s   空间限制: 128000 KB   题目等级 : 白银 Silver 题目描述 Description 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的 ...

  7. 各个公司的来源/The etymology of company

    1.List of Company Etymology 下面的维基百科词条是比较有名的一些公司的名称的来源 List of company name etymologies 2.Atmel : adv ...

  8. C++模板实例化(1)

    On-Demand实例化 当C++编译器遇到模板特化的时候,他会利用所给的实参替换对应的模板参数,从而产生该模板的特化.该过程是自动进行的.有时候也会被称为隐式实例化,或者是自动实例化. on-dem ...

  9. VS默认环境设置

    VS2010的工具菜单-->导入导出设置-->重置所有设置

  10. C语言 电梯函数

    #include <stdio.h> #include <time.h> #include <stdlib.h> void test(){//汉字输出 printf ...