[NOI2012]美食节(费用流)
题目描述
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就死了。
所以我们可以动态加边,每增广一次就加一个点。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 49
#define M 109
#define P 809
#define R register
using namespace std;
queue<int>q;
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];
bool vis[M*P];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
struct edge{int n,to,l,f;}e[N*M*P*];
inline void add(int u,int v,int l,int f){
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;e[tot].f=f;
e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=;e[tot].f=-f;
}
inline bool spfa(int s,int t){
memset(dis,0x3f,sizeof(dis));
q.push(s);dis[s]=;fl[s]=2e9;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=;
// cout<<u<<" "<<dis[u]<<endl;
for(R int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(e[i].l&&dis[v]>dis[u]+e[i].f){
dis[v]=dis[u]+e[i].f;pre[v]=i;fl[v]=min(fl[u],e[i].l);
if(!vis[v]){vis[v]=;q.push(v);}
}
}
}
return dis[t]!=0x3f3f3f3f;
}
inline void calc(int s,int t){
int x=t;
while(x!=s){
int i=pre[x];
e[i].l-=fl[t];e[i^].l+=fl[t];x=e[i^].to;
}
ans+=dis[t]*fl[t];
}
int main(){
n=rd();m=rd();
for(R int i=;i<=n;++i)p[i]=rd(),sum+=p[i];
for(R int i=;i<=n;++i)for(R int j=;j<=m;++j)a[i][j]=rd();
int now=n;
for(R int i=;i<=m;++i)for(R int j=;j<=sum;++j){
++now;tim[now]=j==?:tim[now-]+;if(j==)id[i]=now;be[now]=i;
}
for(R int i=;i<=n;++i)for(R int j=;j<=m;++j)add(i,id[j],,a[i][j]);
for(R int i=;i<=m;++i)add(id[i],now+,,);
for(R int i=;i<=n;++i)add(,i,p[i],);
while(spfa(,now+)){
calc(,now+);
int x=e[pre[now+]^].to;x++;
add(x,now+,,);
for(int i=;i<=n;++i)add(i,x,,tim[x]*a[i][be[x]]);
}
cout<<ans;
return ;
}
[NOI2012]美食节(费用流)的更多相关文章
- [NOI2012]美食节——费用流(带权二分图匹配)+动态加边
题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...
- 【bzoj2879】[Noi2012]美食节 费用流+动态加边
原文地址:http://www.cnblogs.com/GXZlegend 题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他 ...
- BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )
倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...
- [BZOJ2879][NOI2012]美食节(费用流)
设sm为所有p之和,套路地对每道菜建一个点,将每个厨师拆成sm个点,做的倒数第i道菜的代价为time*i. S向每道菜连边<0,p[i]>(前者为代价后者为流量),i菜到j厨师的第k个点连 ...
- [BZOJ2879] [Noi2012] 美食节 (费用流 & 动态加边)
Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...
- BZOJ.2879.[NOI2012]美食节(费用流SPFA)
题目链接 /* 同"修车":对于每个厨师拆成p个点表示p个时间点,每个人向m个厨师每个时间点连边 这样边数O(nmp)+网络流 ≈O(nm*p^2)(假设SPFA线性) = GG ...
- 【BZOJ 2879】[Noi2012]美食节 费用流
思路同修车,就是多了一个骚气的操作:动态加边,我们通过spfa流的过程可以知道,我们一次只会跑一流量,最后一层边跑过就不会再悔改,所以说我们只会用到一大片里面的很少的点,所以我们如果可以动态加边的话我 ...
- BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点
这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...
- [NOI2012][bzoj2879] 美食节 [费用流+动态加边]
题面 传送门 思路 先看看这道题 修车 仔细理解一下,这两道题是不是一样的? 这道题的不同之处 但是有一个区别:本题中每一种车有多个需求,但是这个好办,连边的时候容量涨成$p\lbrack i\rbr ...
随机推荐
- httpd sshd firewalld 服务后面的d的意思
在操作系统中,一般系统的服务都是以后台进程的方式存在,而且都会常驻系统中,直到关机才结束.这类服务也称Daemon,在Linux系统中就包含许多的Daemon. 判断Daemon最简单的方法就是从名称 ...
- Mysql占用CPU过高如何优化?(转)
原文:http://bbs.landingbj.com/t-0-241441-1.html MySQL处在高负载环境下,磁盘IO读写过多,肯定会占用很多资源,必然CP会U占用过高. 占用CPU过高,可 ...
- Cannot connect to database because the database client
问题描述: arcgis server10.1 arcgis sde10出现下面问题 Cannot connect to database because the database client ...
- Ubuntu中MySql的启动与关闭
安装mysql sudo apt-get install mysql-server sudo apt install mysql-client sudo apt install libmysqlcli ...
- mysql 中出现:不能打开到主机的连接,在端口3306: 连接失败
由于某种原因,在服务器部署,然后mysql就连接不上了, navicat查看数据库正常,telnet怎么都不同,总会卡一会儿说遗失主机,最后终于找到解决办法 http://www.51testing. ...
- 浅谈基于Prism的软件系统的架构设计
很早就想写这么一篇文章来对近几年使用Prism框架来设计软件来做一次深入的分析了,但直到最近才开始整理,说到软件系统的设计这里面有太多的学问,只有经过大量的探索才能够设计出好的软件产品,就本人的理解, ...
- zabbix自定义模板——监控TCP连接状态
TCP十二种连接状态说明 可以使用man netstat查看 LISTEN - 侦听来自远方TCP端口的连接请求: SYN-SENT -在发送连接请求后等待匹配的连接请求: SYN-RECEIVED ...
- java 中的Collection
/* *一. Collection?-------->容器! * * 1.来源于java.util包 非常实用的数据结构! * *二. 方法? * * void clear()删除集合中所有元素 ...
- Python——SMTP发送邮件
一.定义 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式.python的smtplib ...
- iOS应用的性能调试
1.Static Analysis 使用之前先清理一下数据:product-->Clean 可能遇到的问题: a.发现工程中有多个“User-facing text should use loc ...