传送门

模型

网络优化问题,用最小费用最大流解决。

实现

把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。

1、从S向每个Xi连一条容量为ri,费用为0的有向边。

2、从每个Yi向T连一条容量为ri,费用为0的有向边。

3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。

4、从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。

5、从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。

6、从每个Xi向Yi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。

求网络最小费用最大流,费用流值就是要求的最小总花费。

分析

这个问题的主要约束条件是每天的餐巾够用,而餐巾的来源可能是最新购买,也可能是前几天送洗,今天刚刚洗好的餐巾。每天用完的餐巾可以选择送到快洗部或慢洗部,或者留到下一天再处理。

经过分析可以把每天要用的和用完的分离开处理,建模后就是二分图。二分图X集合中顶点Xi表示第i天用完的餐巾,其数量为ri,所以从S向Xi连接容量为ri的边作为限制。Y集合中每个点Yi则是第i天需要的餐巾,数量为ri,与T连接的边容量作为限制。每天用完的餐巾可以选择留到下一天(Xi->Xi+1),不需要花费,送到快洗部(Xi->Yi+m),费用为f,送到慢洗部(Xi->Yi+n),费用为s。每天需要的餐巾除了刚刚洗好的餐巾,还可能是新购买的(S->Yi),费用为p。

在网络上求出的最小费用最大流,满足了问题的约束条件(因为在这个图上最大流一定可以使与T连接的边全部满流,其他边只要有可行流就满足条件),而且还可以保证总费用最小,就是我们的优化目标。

还是得好好理解这个建图。

然而这个代码在洛谷上超时了,不会zkw费用流QAQ

——代码

 #include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 4010
#define M 100005
#define INF ~(1 << 31)
#define min(x, y) ((x) < (y) ? (x) : (y)) int a, p, m, f, n, g, s, t, cnt;
int head[N], to[M], val[M], cost[M], next[M], dis[N], pre[N];
bool vis[N];
long long sum; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void add(int x, int y, int z, int c)
{
to[cnt] = y;
val[cnt] = z;
cost[cnt] = c;
next[cnt] = head[x];
head[x] = cnt++;
} inline bool spfa()
{
int i, u, v;
std::queue <int> q;
memset(vis, , sizeof(vis));
memset(pre, -, sizeof(pre));
memset(dis, / , sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
vis[u] = ;
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] > dis[u] + cost[i])
{
dis[v] = dis[u] + cost[i];
pre[v] = i;
if(!vis[v])
{
q.push(v);
vis[v] = ;
}
}
}
}
return pre[t] ^ -;
} int main()
{
int i, x, d;
a = read();
s = , t = (a << ) + ;
memset(head, -, sizeof(head));
for(i = ; i <= a; i++)
{
x = read();
add(s, i, x, ), add(i, s, , );
add(i + a, t, x, ), add(t, i + a, , );
}
p = read();
m = read();
f = read();
n = read();
g = read();
for(i = a + ; i <= a + a; i++) add(s, i, INF, p), add(i, s, , -p);
for(i = ; i < a; i++) add(i, i + , INF, ), add(i + , i, , );
for(i = ; i <= a - m; i++) add(i, i + a + m, INF, f), add(i + a + m, i, , -f);
for(i = ; i <= a - n; i++) add(i, i + a + n, INF, g), add(i + a + n, i, , -g);
while(spfa())
{
d = 1e9;
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]]) d = min(d, val[i]);
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]])
{
val[i] -= d;
val[i ^ ] += d;
}
sum += (long long)dis[t] * d;
}
printf("%lld\n", sum);
return ;
}

[luoguP1251] 餐巾计划问题(费用流)的更多相关文章

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

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

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

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

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

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

  4. LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图

    #6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  5. Vijos1891 学姐的逛街计划 【费用流】*

    Vijos1891 学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课. 偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, ...

  6. HDU 6118 2017百度之星初赛B 度度熊的交易计划(费用流)

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. 【bzoj3291】Alice与能源计划 模拟费用流+二分图最大匹配

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验. 为了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  8. 【HDOJ6118】度度熊的交易计划(费用流)

    题意: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...

  9. HDU 6118 度度熊的交易计划(费用流)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6118 [题目大意] 给出一张无向边权图,每个点最多可以生产b[i]商品,每件代价为a[i], 每个 ...

随机推荐

  1. [uva]AncientMessages象形文字识别 (dfs求连通块)

    非常有趣的一道题目,大意是给你六种符号的16进制文本,让你转化成二进制并识别出来 代码实现上参考了//http://blog.csdn.net/u012139398/article/details/3 ...

  2. 香港城市大学:全球首创3D打印微型机器人技术 有望作治疗癌症用途

    香港城市大学(香港城大)的研究团队开发出了全球首创以磁力控制的3D打印微型机器人,该微型机器人技术能做到在生物体内精准运载细胞到指定的位置.新研发的微型机器人有望应用在治疗癌症的靶向治疗,并为细胞层面 ...

  3. SpringMVC-常用的注解

    1. RequestParam注解 把请求中的指定名称的参数传递给控制器中的形参赋值 value:请求参数中的名称 require:请求参数中是否必须提供此参数,默认值是true,必须提供 2. Re ...

  4. 查询linux文件的MD5值

    Linux下查询文件的MD5值:md5sum xxx.iso.md5 MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.MD5全称是报文摘要算法(Message-Digest Algor ...

  5. 使用MySQL yum源安装MySQL

    #首先,将MySQL Yum存储库添加到系统的存储库列表中. #在https://dev.mysql.com/downloads/repo/yum/地址中,下载mysql yum repository ...

  6. Linux-Java安装

    安装 yum -y install java-1.8.0-openjdk* Tomcat安装:到官网http://tomcat.apache.org/,然后找到Tomcat9下载地址 http://m ...

  7. 标准C++(1)

    一.引用 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符 &引用名=目标变量名: 例: int& num; 引用类似于起别名 注 ...

  8. Java求字符串中出现次数最多的字符

    Java求字符串中出现次数最多的字符  [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51933611      Java ...

  9. HashMap存储原理

    1.    HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. ...

  10. 实验4 —— [bx]和loop的使用

    实验 综合使用 loop.[bx],编写完整汇编程序,实现向内存 b800:07b8 开始的连续 16 个字单元重复填充字数据 0403H. 以下为示例程序: assume cs:code # 1 c ...