题目链接

我做的网络流24题里的第一题。。

想是不可能想到的,只能看题解。

首先,我们拆点,将一天拆成晚上和早上,每天晚上会受到脏餐巾(来源:当天早上用完的餐巾,在这道题中可理解为从原点获得),每天早上又有干净的餐巾(来源:购买、快洗店、慢洗店)。

1.从原点向每一天晚上连一条流量为当天所用餐巾x,费用为0的边,表示每天晚上从起点获得x条脏餐巾。

2.从每一天早上向汇点连一条流量为当天所用餐巾x,费用为0的边,每天白天,表示向汇点提供x条干净的餐巾,流满时表示第i天的餐巾够用 。

3.从每一天晚上向第二天晚上连一条流量为INF,费用为0的边,表示每天晚上可以将脏餐巾留到第二天晚上(注意不是早上,因为脏餐巾在早上不可以使用)。

4.从每一天晚上向这一天+快洗所用天数t1的那一天早上连一条流量为INF,费用为快洗所用钱数的边,表示每天晚上可以送去快洗部,在地i+t1天早上收到餐巾 。

5.同理,从每一天晚上向这一天+慢洗所用天数t2的那一天早上连一条流量为INF,费用为慢洗所用钱数的边,表示每天晚上可以送去慢洗部,在地i+t2天早上收到餐巾 。

6.从起点向每一天早上连一条流量为INF,费用为购买餐巾所用钱数的边,表示每天早上可以购买餐巾 。 注意,以上6点需要建反向边!3~6点需要做判断(即连向的边必须<=n)

(懒得写了)(摘自洛谷题解)

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define INF 2147483647
typedef long long ll;
const int MAXN = 4010;
const int MAXM = 40010;
queue <int> q;
int s, t, now, n, m;
struct Edge{
int from, next, to, rest, cost;
}e[MAXM];
int head[MAXN], num = 1, vis[MAXN], Flow[MAXN], pre[MAXN];
ll dis[MAXN], mincost;
inline void Add(int from, int to, int flow, int cost){
e[++num] = (Edge){ from, head[from], to, flow, cost }; head[from] = num;
e[++num] = (Edge){ to, head[to], from, 0, -cost }; head[to] = num;
}
int RoadsExist(){
q.push(s);
memset(dis, 127, sizeof dis);
dis[s] = 0; Flow[s] = INF; pre[t] = 0;
while(!q.empty()){
now = q.front(); q.pop(); vis[now] = 0;
for(int i = head[now]; i; i = e[i].next)
if(e[i].rest && dis[e[i].to] > dis[now] + e[i].cost){
dis[e[i].to] = dis[now] + e[i].cost;
pre[e[i].to] = i;
Flow[e[i].to] = min(Flow[now], e[i].rest);
if(!vis[e[i].to]){
vis[e[i].to] = 1;
q.push(e[i].to);
}
}
}
return pre[t];
}
int a[MAXN], buy, qw, qc, sw, sc;
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d%d%d%d%d", &buy, &qw, &qc, &sw, &sc);
s = (n << 1) + 1; t = s + 1;
for(int i = 1; i <= n; ++i){
Add(s, i << 1, a[i], 0);
Add((i << 1) - 1, t, a[i], 0);
Add(s, (i << 1) - 1, INF, buy);
if(i != n) Add(i << 1, (i + 1) << 1, INF, 0);
if(i + qw <= n) Add(i << 1, ((i + qw) << 1) - 1, INF, qc);
if(i + sw <= n) Add(i << 1, ((i + sw) << 1) - 1, INF, sc);
}
while(RoadsExist()){
mincost += Flow[t] * dis[t];
for(int i = t; i != s; i = e[pre[i]].from){
e[pre[i]].rest -= Flow[t];
e[pre[i] ^ 1].rest += Flow[t];
}
}
printf("%lld\n", mincost);
return 0;
}

【洛谷 P1251】 餐巾计划问题 (费用流)的更多相关文章

  1. 洛谷.1251.餐巾计划问题(费用流SPFA)

    题目链接 /* 每一天的餐巾需求相当于必须遍历某些点若干次 设q[i]为Dayi需求量 (x,y)表示边x容y费 将每个点i拆成i,i',由i'->T连(q[i],0)的边,表示求最大流的话一定 ...

  2. 洛谷 P1251 餐巾计划问题(线性规划网络优化)【费用流】

    (题外话:心塞...大部分时间都在debug,拆点忘记加N,总边数算错,数据类型标错,字母写错......) 题目链接:https://www.luogu.org/problemnew/show/P1 ...

  3. 洛谷P1251 餐巾计划问题(最小费用最大流)

    题意 一家餐厅,第$i$天需要$r_i$块餐巾,每天获取餐巾有三种途径 1.以$p$的费用买 2.以$f$的费用送到快洗部,并在$m$天后取出 3.以$s$的费用送到慢洗部,并在$n$天后取出 问满足 ...

  4. [洛谷P1251]餐巾计划问题

    题目大意:一个餐厅N天,每天需要$r_i$块餐巾.每块餐巾需要p元,每天用过的餐巾变脏,不能直接用.现在有快洗店和慢洗店,快洗店洗餐巾需要m天,每块花费f元:慢洗店洗餐巾需要n天,每块餐巾s元(m & ...

  5. 洛谷 P1251 餐巾计划问题

    题目链接 最小费用最大流. 每天拆成两个点,早上和晚上: 晚上可以获得\(r_i\)条脏毛巾,从源点连一条容量为\(r_i\),费用为0的边. 早上要供应\(r_i\)条毛巾,连向汇点一条容量为\(r ...

  6. 洛谷P1251 餐巾计划问题(费用流)

    传送门 不得不说这题真是思路清奇,真是网络流的一道好题,完全没想到网络流的建图还可以这么建 我们把每一个点拆成两个点,分别表示白天和晚上,白天可以得到干净的餐巾(购买的,慢洗的,快洗的),晚上可以得到 ...

  7. 洛谷 P1251 餐巾计划问题【最小费用最大流】

    建图细节比较多,对于每个点i,拆成i和i',i表示用的餐巾,i'表示脏餐巾,连接: (s,i,r[i],p)表示在这一天买新餐巾 (i,t,r[i],0)表示这一天用了r[i]的餐巾 (s,i+n,r ...

  8. P1251 餐巾计划问题 费用流

    https://www.luogu.org/problemnew/show/P1251 题意 有一家酒店,酒店每天需要ri张桌布,桌布可以现买,p元.可以通过快洗店,等m天,f元.可以通过慢洗店,等n ...

  9. LuoguP1251 餐巾计划问题(费用流)

    题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri​块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送 ...

  10. 洛谷P1251 餐巾(网络流)

    P1251 餐巾 15通过 95提交 题目提供者该用户不存在 标签网络流贪心 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 为什么我全部10个测试点都对… 题目描述 一个餐厅在相继的N天里 ...

随机推荐

  1. Delphi实例之橡皮筋画图的实现

    Delphi实例之橡皮筋画图的实现 在<Delphi7基础教程>这本书的练习中提到过一个橡皮筋画图的例子,书上的源码是错误的!不知道是打印的错误还是本身源码就有问题,我将它改了过来. 在F ...

  2. 玩转Node.js(四)-搭建简单的聊天室

    玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...

  3. 【APUE】Chapter1 UNIX System Overview

    这章内容就是“provides a whirlwind tour of the UNIX System from a programmer's perspective”. 其实在看这章内容的时候,已经 ...

  4. 第十七篇 Python函数之闭包与装饰器

    一. 装饰器 装饰器:可以拆解来看,器本质就是函数,装饰就是修饰的意思,所以装饰器的功能就是为其他函数添加附加功能. 装饰器的两个原则: 1. 不修改被修饰函数的源代码 2. 不修改被修饰函数的调用方 ...

  5. (原创)最小生成树之Prim(普里姆)算法+代码详解,最懂你的讲解

    Prim算法 (哈欠)在创建最小生成树之前,让我们回忆一下什么是最小生成树.最小生成树即在一个待权值的图(即网结构)中用一个七拐八绕的折线串连起所有的点,最小嘛,顾名思义,要权值相加起来最小,你当然可 ...

  6. ubuntu安装显卡驱动和cuda

    NVIDIA-linux.run安装后,会出现登录页面循环,解决办法是在运行命令后加入-no-opengl-files 打开nvidia x server Settings软件,显示:You do n ...

  7. Cassandra - Insert after Delete fails silently

    在delete一条数据后,再insert 相同内容的数据,结果看起来是成功的,但是当你去查找这个数据,却没有任何内容,整个过程并且没有任何异常提示. 这往往发生在单元测试的时候,我们反复清理和写入数据 ...

  8. 测试理论- the conten of test plan

    1 testing objects 测试对象 2 testing scope 测试范围 3 testing the frame (?) 4 the environment 5 reason for t ...

  9. edgeboxes proposal 和dpm 连接

    经过多天阅读文献和代码,我对edgeboxes 和 dpm的有了一定了解. 现在决定把它们简单地连接起来 也就是edgeboxes proposal 推荐窗口 然后 dpm去判断 但按照我理解的DPM ...

  10. spring环境搭建(简单实例)

    1使用Maven导入需要的依赖(在project标签下) <properties> <spring_version>3.2.2.RELEASE</spring_versi ...