题意

一家餐厅,第$i$天需要$r_i$块餐巾,每天获取餐巾有三种途径

1、以$p$的费用买

2、以$f$的费用送到快洗部,并在$m$天后取出

3、以$s$的费用送到慢洗部,并在$n$天后取出

问满足要求时的最小费用

Sol

一道非常不错的网络流,应该不难看出是费用流。

首先进行拆点,把每个点早上和晚上,然后进行连边

从$S$向i连边$(0, r_i)$,表示到了晚上有$r_i$块脏餐巾

从$i'$向$T$连边$(0, r_i)$,表示早上有$r_i$块新餐巾

从$S$向$i'$连边$(p, INF)$,表示每天早上可以以$p$的费用无限提供餐巾

从$i$向$i'$连边$(0, INF)$,表示每天晚上的脏餐巾可以留到第二天晚上

从$i$向$i' + m$连边$(f, INF)$,表示快洗

从$i$向$i' + n$连边$(s, INF)$,表示慢洗

这样既可以保证每天的$r_i$满足要求,又能保证最小费用。so nice

#include<cstdio>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
const int MAXN = 1e5 + , INF = 1e9 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, S, T;
int r[MAXN], p, m, f, n, s;
struct Edge {
int u, v, w, f, nxt;
}E[MAXN];
int head[MAXN], num;
inline void add_edge(int x, int y, int w, int f) {
E[num] = (Edge){x, y, w, f, head[x]};
head[x] = num++;
}
inline void AddEdge(int x, int y, int w, int f) {
add_edge(x, y, w, f);
add_edge(y, x, -w, );
}
int dis[MAXN], vis[MAXN], Pre[MAXN];
bool SPFA() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, , sizeof(vis));
queue<int> q; dis[S] = ; q.push(S);
while(!q.empty()) {
int p = q.front(); q.pop(); vis[p] = ;
for(int i = head[p]; i != -; i = E[i].nxt) {
int to = E[i].v;
if(dis[to] > dis[p] + E[i].w && E[i].f) {
dis[to] = dis[p] + E[i].w;
Pre[to] = i;
if(!vis[to]) vis[to] = , q.push(to);
}
}
}
return dis[T] <= INF;
}
LL F() {
LL nowflow = INF;
for(int i = T; i != S; i = E[Pre[i]].u) nowflow = min(nowflow, (LL)E[Pre[i]].f);
for(int i = T; i != S; i = E[Pre[i]].u) E[Pre[i]].f -= nowflow, E[Pre[i] ^ ].f += nowflow;
return nowflow * dis[T];
}
LL MCMF() {
LL ans = ;
while(SPFA())
ans += F();
return ans;
}
int main() {
memset(head, -, sizeof(head));
N = read();
S = ; T = * N + ;
for(int i = ; i <= N; i++) r[i] = read();
p = read(); m = read(); f = read(); n = read(); s = read();
for(int i = ; i <= N; i++) AddEdge(S, i, , r[i]);
for(int i = ; i <= N; i++) AddEdge(S, i + N, p, INF);
for(int i = ; i <= N; i++) AddEdge(i + N, T, , r[i]);
for(int i = ; i <= N; i++) {
if(i + m <= N) AddEdge(i, i + N + m, f, INF);
if(i + n <= N) AddEdge(i, i + N + n, s, INF);
if(i + <= N) AddEdge(i, i + , , INF);
}
printf("%lld", MCMF());
}

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

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

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

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

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

  3. 洛谷 P1251 餐巾计划问题

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

  4. 洛谷P3381 - 【模板】最小费用最大流

    原题链接 题意简述 模板题啦~ 题解 每次都以费用作为边权求一下最短路,然后沿着最短路增广. Code //[模板]最小费用最大流 #include <cstdio> #include & ...

  5. 洛谷 P2053 [SCOI2007]修车(最小费用最大流)

    题解 最小费用最大流 n和m是反着的 首先, \[ ans = \sum{cost[i][j]}*k \] 其中,\(k\)为它在当前技术人员那里,排倒数第\(k\)个修 我们可以对于每个技术人员进行 ...

  6. 洛谷 P3381【模板】最小费用最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表 ...

  7. 洛谷 P3381 【模板】最小费用最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数\(N.M.S.T\) ...

  8. 洛谷P3381 【模板】最小费用最大流(dijstra费用流)

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表 ...

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

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

随机推荐

  1. 序列化FastReport,重要提示少走弯路 good

    原本在开发一个报表插件,因为需要远程传输,因此需要序列化报表,序列化FastReport有两种方式, 1.仅序列化数据,由客户端接受到数据,并呈现报表,这种方式需要在客户端存储报表格式文件xxx.Fr ...

  2. android user 版本如何默认adb调试为打开【转】

    本文转载自:http://blog.csdn.net/chaihuasong/article/details/50342119 A. 软件准备 user版本需要先打开USB debug开关,打开方式如 ...

  3. POJ3258 River Hopscotch —— 二分

    题目链接:http://poj.org/problem?id=3258 River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total ...

  4. hdu 2680 Choose the best route 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2680 题目意思:实质就是给定一个多源点到单一终点的最短路. 卑鄙题---有向图.初始化map时 千万不 ...

  5. Swagger测试工具

    http://www.360doc.com/content/16/0509/08/1355383_557462195.shtml

  6. LA-2678 (尺取法)

    题意: 在一个长度为n的序列中,找到最短的长度序列,使其和大于等于s; 思路: two pointer ,水题; Ac代码: #include <bits/stdc++.h> /* #in ...

  7. 并不对劲的bzoj5475:loj2983:p5206:[wc2019]数树

    题目大意 task0:有两棵\(n\)(n\leq10^5)个点的树\(T1,T2\),每个点的点权可以是一个在\([1,y]\)里的数,如果两个点既在\(T1\)中有直接连边,又在\(T2\)中有直 ...

  8. [POI 2014] Little Bird

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3831 [算法] 单调队列优化动态规划 时间复杂度 : O(N) [代码] #incl ...

  9. JAVA 中 synchronized 详解

    看到一篇关于JAVA中synchronized的用法的详解,觉得不错遂转载之..... 原文地址: http://www.cnblogs.com/GnagWang/archive/2011/02/27 ...

  10. JAVA Synchronized (二)

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...