餐巾计划问题 zwk费用流解法
«问题描述:
一个餐厅在相继的N 天里,每天需用的餐巾数不尽相同。假设第i天需要ri块餐巾(i=1,
2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为p分;或者把旧餐巾送到快洗部,
洗一块需m天,其费用为f 分;或者送到慢洗部,洗一块需n 天(n>m),其费用为s<f 分。
每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多
少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。
试设计一个算法为餐厅合理地安排好N 天中餐巾使用计划,使总的花费最小。
«编程任务:
编程找出一个最佳餐巾使用计划.
«数据输入:
由文件input.txt提供输入数据。文件第1 行有6 个正整数N,p,m,f,n,s。N 是要安排餐巾
使用计划的天数;p 是每块新餐巾的费用;m 是快洗部洗一块餐巾需用天数;f 是快洗部洗
一块餐巾需要的费用;n是慢洗部洗一块餐巾需用天数;s是慢洗部洗一块餐巾需要的费用。
接下来的N 行是餐厅在相继的N 天里,每天需用的餐巾数。
«结果输出:
程序运行结束时,将餐厅在相继的N 天里使用餐巾的最小总花费输出到文件output.txt
中。
建立源点S汇点T,并把每一天拆分为入点与出点,
以ai表示第i天需要的餐巾数量
S向每天的入点连一条容量ai,费用0的边表示新产生的脏餐巾数
每天的入点向下一天的入点连一条容量无限大,费用0的边表示转移到下一天的脏餐巾
每天的入点向m天后的出点连一条容量无限大,费用f的边表示送去快洗部洗餐巾
每天的入点向n天后的出点连一条容量无限大,费用s的边表示送去慢洗部洗餐巾
每天的出点向T连一条容量ai,费用0的边表示当天需要的干净餐巾
zwk费用流的实现细节解释在代码注释中
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int MAXN=;
const int maxn=;
const int INF=~0U>>;
long long int maxflow=,cost=;
int v[maxn],dis[maxn];
int r[maxn];
int S,T;
int N,p,m,f,n,s;
int tot=;
int pointer[maxn];
struct Edge
{
int to,next,cap,op,f,w;
Edge() {};
Edge(int b,int c,int nxt,int num,int flow,int weight) {to=b,cap=c,next=nxt,op=num^,f=flow,w=weight;}
}edge[MAXN];
inline void addedge(int a,int b,int c,int w1)
{
edge[tot]=Edge(b,c,pointer[a],tot,,w1);
pointer[a]=tot++;
edge[tot]=Edge(a,,pointer[b],tot,,-w1);
pointer[b]=tot++;
}
inline int aug(int x,int flow) //dfs搜增光路 flow代表当前dfs路径中剩余容量最小边的容量
{
if(x==T)
{
maxflow+=flow;
cost+=dis[S]*flow;
return flow;
}
v[x]=;
int l=flow;
for(int j=pointer[x];j!=-;j=edge[j].next)
{
int y=edge[j].to;
if(!v[y]&&edge[j].cap-edge[j].f&&dis[y]+edge[j].w==dis[x]) //距离标号满足要求代表走的这一步是目前情况下到达y的最短路其中的一步
{
int tmp=aug(y,min(l,edge[j].cap-edge[j].f)); //
edge[j].f+=tmp,edge[j^].f-=tmp,l-=tmp; //x-->y这条路分走了tmp大小的流量
if(!l) return flow; //到达x点的flow大小的流量被分完了就不必考虑x的其他子节点了
}
}
return flow-l;
}
inline bool modlabel()
{
int minh=INF;
rep(i,S,T)
{
if(v[i])
for(int j=pointer[i];j!=-;j=edge[j].next)
{
int y=edge[j].to;
if(edge[j].cap-edge[j].f>&&!v[y])
{
minh=min(minh,dis[y]+edge[j].w-dis[i]);
}
}
}
if(minh==INF) return ;
rep(i,S,T) if(v[i]) dis[i]+=minh; //利用距离标号控制最短路条件
return ;
}
inline void zwk()
{
do
{
do
{
rep(i,S,T) v[i]=;
}while(aug(S,INF));
}while(modlabel());
}
inline void init()
{
memset(pointer,-,sizeof(pointer));
scanf("%d%d%d%d%d%d",&N,&p,&m,&f,&n,&s);
S=;T=*N+;
int ri;
rep(i,,N)
{
scanf("%d",&ri);
addedge(S,i,ri,);
addedge(N+i,T,ri,);
addedge(S,N+i,INF,p);
if(i+m<=N) addedge(i,N+i+m,INF,f);
if(i+n<=N) addedge(i,N+i+n,INF,s);
if(i<N) addedge(i,i+,INF,);
}
}
int main()
{
freopen("napk10.in","r",stdin);
init();
zwk();
printf("%lld\n",cost);
return ;
}
餐巾计划问题 zwk费用流解法的更多相关文章
- 【Codevs1237&网络流24题餐巾计划】(费用流)
题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 ...
- [luoguP1251] 餐巾计划问题(费用流)
传送门 模型 网络优化问题,用最小费用最大流解决. 实现 把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T. 1.从S向每个Xi连一条容量为ri,费用为0的有向边. 2.从每个Yi向T连一 ...
- 洛谷P1251 餐巾计划问题(费用流)
传送门 不得不说这题真是思路清奇,真是网络流的一道好题,完全没想到网络流的建图还可以这么建 我们把每一个点拆成两个点,分别表示白天和晚上,白天可以得到干净的餐巾(购买的,慢洗的,快洗的),晚上可以得到 ...
- 【洛谷 P1251】 餐巾计划问题 (费用流)
题目链接 我做的网络流24题里的第一题.. 想是不可能想到的,只能看题解. 首先,我们拆点,将一天拆成晚上和早上,每天晚上会受到脏餐巾(来源:当天早上用完的餐巾,在这道题中可理解为从原点获得),每天早 ...
- 线性规划费用流解法(Bzoj1061: [Noi2008]志愿者招募)
题面 传送门 Sol 线性规划费用流解法用与求解未知数为非负数的问题 这道题可以列出一堆形如 \(x[i]+x[j]+x[k]+...>=a[p]\) 的不等式 我们强行给每个式子减去一个东西, ...
- 洛谷P1251 餐巾计划问题(最小费用最大流)
题意 一家餐厅,第$i$天需要$r_i$块餐巾,每天获取餐巾有三种途径 1.以$p$的费用买 2.以$f$的费用送到快洗部,并在$m$天后取出 3.以$s$的费用送到慢洗部,并在$n$天后取出 问满足 ...
- 刷题总结——学姐的逛街计划(vijos1891费用流)
题目: doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, 因为他还要陪学姐去逛街呢. 后来, ...
- P1251-餐巾计划问题【费用流】
正题 题目链接:https://www.luogu.com.cn/problem/P1251 题目大意 \(N\)天,第\(i\)天需要\(a_i\)个餐巾. 每个餐巾价格为\(p\),使用完后有两种 ...
- P4480 「BJWC2018」「网络流与线性规划24题」餐巾计划问题
刷了n次用了奇淫技巧才拿到rk1,亥 这道题是网络流二十四题中「餐巾计划问题」的加强版. 于是怀着试一试的心情用费用流交了一发: 哇塞,过了9个点!(强烈谴责出题人用*造数据 下面是费用流解法简述: ...
随机推荐
- jackson实体转json时 为NULL不参加序列化的汇总
首先加入依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson ...
- ReactiveCocoa入门教程--第二部分
翻译自:http://www.raywenderlich.com/62796/reactivecocoa-tutorial-pt2 ReactiveCocoa 是一个框架,它允许你在你的iOS程序中使 ...
- CentOS中/英文环境切换教程(CentOS6.8)
一.前言 对于不习惯英文的人可能想将系统由英文转成中文:而对于考虑客户端如果没正确配置,中文目录可能显示为乱码的人则可能宁愿将系统由中文转成英文. 中文切换为英文,实际就是将LANG的值由zh_CN- ...
- QPainter使用不同风格的QBrush来填充区域
效果图: void WgtText::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QP ...
- 我个人对OOP的理解
OOP面向对象的思维:pay1:封装 A.避免使用非法数据赋值 B.保证数据的完整性 C.避免类内部发生修改的时候,导致整个程序的修改 pay2:继承 A.继承模拟了现实世界的关系,OOP中强调一切皆 ...
- 回声UDP服务器端/客户端
UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要.输入函数的调用次数要和输出函数的调用次数完全一致,这样才能保证接受全部已发送的数据. TCP套接字中需注册待传输数据的目标IP和端口,而 ...
- linux的典型分支:
1.redhat 2.debian 3.centOS 4.ubuntu 5.fedora 6.kali linux
- Win10系列:UWP界面布局进阶8
StackPanel StackPanel能够以水平或垂直的方式整齐地排列位于其内部的元素.通过设置StackPanel的Orientation属性可以定义内部元素的排列方式,当将Orientatio ...
- TCP/UDP工作流程图
说到socket必须要贴的图: TCP工作流程: UDP工作流程:
- hMailServer 配置
本例记录如何通过 [hMailServer] 在私有服务器中搭建邮件服务器 1.下载安装包 版本: hMailServer-5.6.7-B2425.exe (支持使用内置数据库) , 安装时,设置管 ...