BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点
这道题就是“修车”的数据加强版……但是数据范围扩大了好多,应对方法是“动态开点”。
首先先把“所有厨师做的倒数第一道菜”和所有菜连边,然后跑一下spfa,找出哪一个厨师在增广路上,把“这个厨师做的倒数第二道菜”和所有菜连边,然后继续spfa,如此循环往复直到spfa找不出最短路。
#include <queue>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#define space putchar(' ')
#define enter putchar('\n')
typedef long long ll;
using namespace std;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 100005, M = 10000005, INF = 0x3f3f3f3f;
int n, m, src, des, tot, ans, sum;
int cook[105][805], dish[805], id[N], rnk[N], w[45][105], p[45];
int ecnt = 1, adj[N], dis[N], pre[N], nxt[M], go[M], cap[M], cost[M];
void _add(int u, int v, int w, int c){
go[++ecnt] = v;
nxt[ecnt] = adj[u];
adj[u] = ecnt;
cap[ecnt] = w;
cost[ecnt] = c;
}
void add(int u, int v, int w, int c){
_add(u, v, w, c);
_add(v, u, 0, -c);
}
bool spfa(){
queue <int> que;
static bool inq[N] = {0};
for(int i = 1; i <= tot; i++)
dis[i] = INF, pre[i] = 0;
dis[src] = 0, que.push(src), inq[src] = 1;
while(!que.empty()){
int u = que.front();
que.pop(), inq[u] = 0;
for(int e = adj[u], v; e; e = nxt[e]){
if(cap[e] && dis[u] + cost[e] < dis[v = go[e]]){
dis[v] = dis[u] + cost[e], pre[v] = e;
if(!inq[v]) que.push(v), inq[v] = 1;
}
}
}
return dis[des] < INF;
}
int main(){
read(n), read(m);
src = ++tot, des = ++tot;
for(int i = 1; i <= n; i++)
read(p[i]), sum += p[i];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
read(w[i][j]);
for(int i = 1; i <= n; i++){
dish[i] = ++tot, id[tot] = i;
add(src, dish[i], p[i], 0);
}
for(int i = 1; i <= m; i++){
cook[i][1] = ++tot, id[tot] = i, rnk[tot] = 1;
add(cook[i][1], des, 1, 0);
for(int j = 1; j <= n; j++)
add(dish[j], cook[i][1], 1, w[j][i]);
}
while(spfa()){
int tmp = go[pre[des] ^ 1], _cook = id[tmp], _rank = rnk[tmp], flow = INF;
for(int e = pre[des]; e; e = pre[go[e ^ 1]])
flow = min(flow, cap[e]);
for(int e = pre[des]; e; e = pre[go[e ^ 1]])
cap[e] -= flow, cap[e ^ 1] += flow;
ans += flow * dis[des];
cook[_cook][_rank + 1] = ++tot, id[tot] = _cook, rnk[tot] = _rank + 1;
add(tot, des, 1, 0);
for(int i = 1; i <= n; i++)
add(dish[i], tot, 1, w[i][_cook] * (_rank + 1));
}
write(ans), enter;
return 0;
}
BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点的更多相关文章
- BZOJ 2879: [Noi2012]美食节( 费用流 + 动态加边 )
倒着做菜..然后考虑为当前的人做菜对后面的人的影响就可以了..要动态加边 --------------------------------------------------------------- ...
- BZOJ.2879.[NOI2012]美食节(费用流SPFA)
题目链接 /* 同"修车":对于每个厨师拆成p个点表示p个时间点,每个人向m个厨师每个时间点连边 这样边数O(nmp)+网络流 ≈O(nm*p^2)(假设SPFA线性) = GG ...
- 【bzoj2879】[Noi2012]美食节 费用流+动态加边
原文地址:http://www.cnblogs.com/GXZlegend 题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他 ...
- [BZOJ2879] [Noi2012] 美食节 (费用流 & 动态加边)
Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽 ...
- BZOJ 2879: [Noi2012]美食节 最小费用流 动态添边
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 324 Solved: 179[Submit][Status] ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- [NOI2012]美食节——费用流(带权二分图匹配)+动态加边
题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...
- [NOI2012][bzoj2879] 美食节 [费用流+动态加边]
题面 传送门 思路 先看看这道题 修车 仔细理解一下,这两道题是不是一样的? 这道题的不同之处 但是有一个区别:本题中每一种车有多个需求,但是这个好办,连边的时候容量涨成$p\lbrack i\rbr ...
- [NOI2012]美食节(费用流)
题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...
随机推荐
- TensorFlow(1):使用Docker镜像搭建TensorFlow环境
1,关于TensorFlow TensorFlow 随着AlphaGo的胜利也火了起来. google又一次成为大家膜拜的大神了.google大神在引导这机器学习的方向. 同时docker 也是一个非 ...
- 2017-2018-2 20155203《网络对抗技术》 Exp7:网络欺诈防范
1.基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 连接无线网络,和恶意攻击者处在同一局域网下. (2)在日常生活工作中如何防范以上两攻击方法 首先决不去点击浏览器都认为不安全的网 ...
- 20155226 Exp2 后门原理与实践
20155226 Exp2 后门原理与实践 第一次实验博客交了蓝墨云未在博客园提交,链接 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机 ...
- MySQL优化:explain using temporary
什么时候会使用临时表:group/order没设计好的时候 1.order没用索引 2.order用了索引, 但不是和where相同的索引 3.order用了两个索引, 但不是联合索引 4.order ...
- 10、MySQL 的复制
10.1 复制的概述 10.2 配置复制 10.3 复制的原理 有两种 1.基于sql语句的复制:传输数据少(sql语句文件),就能复制大量的数据,不过由于一些自定义的函数问题,会有一些限制: 2.基 ...
- Luogu P2055 [ZJOI2009]假期的宿舍
一道网络有关的问题,还是一句话 网络流重在建模! 这里主要讲两种算法. 1.二分图匹配: 分析题意,我们可以知道题目要求是让所有留在学校的人都能有床睡 而 所有留在学校的人=本校不回家的人+外校的人: ...
- [CF1083F]The Fair Nut and Amusing Xor[差分+同余分类+根号分治+分块]
题意 给定两个长度为 \(n\) 的序列 \(\{a_i\}\) 与 \(\{b_i\}\),你需要求出它们的相似度.,我们定义这两个序列的相似度为将其中一个序列转化为另一个序列所需的最小操作次数.一 ...
- 利用Junit实现eclipse单元测试
在eclipse中使用Junit进行单元测试 今天学会了用Junit在eclipse中进行单元测试,代码的测试工作,在整个软件开发中占有总要的地位,无论是代码开发阶段,还是代码维护阶段.另外边开发边测 ...
- Asp.Net_序列化、反序列化
.net序列化及反序列化 在我们深入探讨C#序列化和反序列化之前我们先要明白什么是序列化,它又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.序列化就是把一个对象保存到一个文件或数据库 ...
- MFC学习笔记(一): 不用MFC向导如何新建一个MFC程序
使用Visual Studio新建一个空项目,项目命名为HelloMFC,完成后,打开项目属性页面,将配置属性选项卡中的常规项打开,将其中的MFC的使用属性栏改为:在静态库中使用MFC或者在共享DLL ...