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自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...
随机推荐
- 20155325 Exp3 免杀原理与实践
基础问题回答 杀软是如何检测出恶意代码的? 1.1 基于特征码的检测 1.1.1 特征库举例-Snort 1.2 启发式恶意软件检测 1.3 基于行为的恶意软件检测 免杀是做什么? 一般是对恶意软件做 ...
- Lambda学习---方法引用和其他基本应用
package com.zx; import java.util.*; import java.util.function.*; import java.util.stream.Collectors; ...
- NodeJS旅程 : Less
我一直强调我是个很懒的人,虽然我认为自己是个代码控但不代表我喜欢写大量代码.有做Web前端开发的人一定都接触CSS,由其在当下CSS3更是做出Cool站的必修课.我曾和不少的前端开发讨论过CSS3,我 ...
- 浅谈android Service和BroadCastReceiver
1.题记 Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序. 广播接收者(BroadcastRece ...
- MongoDB的账户与权限管理及在Python与Java中的登录
本文主要介绍了MongoDB的账户新建,权限管理(简单的),以及在Python,Java和默认客户端中的登陆. 默认的MongoDB是没有账户权限管理的,也就是说,不需要密码即可登陆,即可拥有读写的权 ...
- npm install的几种命令形式区别
转自未来与传说.jigetage 我们在使用 npm install 安装模块的时候 ,一般会使用下面这几种命令形式: npm install moduleName # 安装模块到项目目录下 npm ...
- Python提示信息表示内容
=此页面列出了PyLint 1.1.0支持的所有消息,按消息文本排序.还有一个按消息代码排序的所有代码列表. E0001,F0001,W0511(消息不同) E0103:循环中%r不正确W1501 ...
- Eclipse,代码中有错误,项目中却不显示红叉
***修改eclipse 代码提示级别1.单个项目修改项目上右键-->properties-->java compiler-->building-->enable projec ...
- Spark 实践——用决策树算法预测森林植被
本文基于<Spark 高级数据分析>第4章 用决策树算法预测森林植被集. 完整代码见 https://github.com/libaoquan95/aasPractice/tree/mas ...
- 从零开始学Kotlin-基础语法(1)
从零开始学Kotlin基础篇系列文章 注释 //单行注释 /* 多行注释 */ /** * 多行注释 */ 定义变量/常量 变量定义:var 关键字 var <标识符> : <类型& ...