初识费用流 模板(spfa+slf优化) 餐巾计划问题
今天学习了最小费用最大流,是网络流算法之一。可以对于一个每条边有一个容量和一个费用(即每单位流的消耗)的图指定一个源点和汇点,求在从源点到汇点的流量最大的前提下的最小费用。
这里讲一种最基础也是最好掌握的实现算法,就是spfa求费用流。
其实也很简单,在最大流的基础上,我们将dfs增广替换成对于费用为权值的边跑spfa得到的最短路,相当于一个贪心的思想。证明有一定难度,稍微口糊一下,就像ford-fulkerson一样,这个算法每次都能找到一条单位流费用和最小的路径,又由于路径中每条边的流量相等,每次增广就能使得单位流量的平均费用更小,而最大流流量是不变的,这样就能使得费用最小。
网络流算法主要考建图,所以模板只要会默下来就够了,还有就是:
一定要会写spfa!!!
对于spfa,这里有两个小优化。
一个是slf优化,就是对于spfa的进队操作,进之前判一下若小于队头就直接插在队头,这个还是蛮有用的,可以提升点速度;
另一个是记路径的时候可以不用记前趋点,只要记边,反向边指向的就是前趋,就不用多开一个数组的空间。(这个是zxyer学长当时说的)
下面贴上代码:
这是网络流24题中的餐巾计划问题。
题目大意是:一个饭馆每天需要使用ri条干净的餐巾,用完就脏了,干净餐巾可以由3种方式得到:
1.直接购买,p元一条;
2.快洗,需要t1天,花费w1元;
3.慢洗,需要t2天,花费w2元;
所以我们建6种边,把每天拆成两个点,分别为干净的(1~n)和脏的(n+1~n*2),这里要注意的是,干净的不直接向脏的连边,而是连向T,相当于必须送满ri条给顾客使用,再从S送到脏的一边。
#include<cstdio>
using namespace std;
const int inf=;
int n,m,p,t1,w1,t2,w2,tot=,mx,q[],d[],pree[],h[];
struct edge{int to,nxt,cst,cap;}e[];
bool vis[];
int mn(int x,int y){return x>y?y:x;}
void add(int fr,int to,int cst,int cap)
{
e[++tot]={to,h[fr],cst,cap};h[fr]=tot;
e[++tot]={fr,h[to],-cst,};h[to]=tot;//建一条容量为0费用为-cap的反向边且满足正反边异或值为1方便将边取反
}
void init()
{
scanf("%d%d%d%d%d%d",&n,&p,&t1,&w1,&t2,&w2);
for(int i=;i<=n;i++)
{
int r;scanf("%d",&r);mx+=r;
add(,n+i,p,inf);//直接购买花费p元
add(,i,,r);//当天用完的旧餐巾
add(i+n,n*+,,r);//当天需要使用的新餐巾
if(i+t1<=n)add(i,i+n+t1,w1,inf);//快洗花费t1时间,每条w1元
if(i+t2<=n)add(i,i+n+t2,w2,inf);//快洗花费t2时间,每条w2元
if(i<n)add(i,i+,,inf);//不需要做任何事的餐巾积到明天(也可以先洗完然后放在那边等就是n+i连向n+i+1)
}
n=n*+;
}
bool spfa()
{
for(int i=;i<=n;i++)d[i]=inf;
int l=,r=;q[]=;vis[]=;
while(l!=r)
{
int x=q[l=l==n?:l+];
for(int i=h[x];i;i=e[i].nxt)
if(e[i].cap&&e[i].cst+d[x]<d[e[i].to])
{
int v=e[i].to;
pree[v]=i;
d[v]=d[x]+e[i].cst;
if(!vis[v])
{
if(d[v]>d[l+])q[r=r==n?:r+]=v;
else q[l]=v,l=l==?n:l-;//这边加的是slf优化,用了循环队列来写
vis[v]=;
}
}
vis[x]=;
}
return d[n]==inf?:;
}
int costflow()
{
int cost=,mm=;
while(spfa())
{
int mi=inf;
for(int i=n;i;i=e[pree[i]^].to)//记路径时记下前趋路径
mi=mn(mi,e[pree[i]].cap);
for(int i=n;i;i=e[pree[i]^].to)
{
int ee=pree[i];
e[ee].cap-=mi;
e[ee^].cap+=mi;
}
cost+=d[n]*mi;
mm+=mi;
}
return mm==mx?cost:;//是否满流的判断(这道题不会出现不满流的情况,所以不加也可)
}
int main()
{
init();
printf("%d",costflow());
return ;
}
初识费用流 模板(spfa+slf优化) 餐巾计划问题的更多相关文章
- 【zkw费用流】[网络流24题]餐巾计划问题
题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...
- 【费用流】【Next Array】费用流模板(spfa版)
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using ...
- HDU 6611 K Subsequence(Dijkstra优化费用流 模板)题解
题意: 有\(n\)个数\(a_1\cdots a_n\),现要你给出\(k\)个不相交的非降子序列,使得和最大. 思路: 费用流建图,每个点拆点,费用为\(-a[i]\),然后和源点连边,和后面非降 ...
- [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- HDU2686 费用流 模板
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- spfa + slf优化
最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 . QwQ,所以就去学了一下优化 . slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我t ...
- hdu1533 费用流模板
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- POJ - 3268 Silver Cow Party SPFA+SLF优化 单源起点终点最短路
Silver Cow Party One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to ...
- 费用流模板(带权二分图匹配)——hdu1533
/* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 1000 ...
随机推荐
- windows与linux下执行.class(包含main方法)
来源:http://blog.csdn.net/hanqunfeng/article/details/4327325 一般来说,执行一个java文件采用执行jar包的方式最为方便(java -jar ...
- 使用 Python 操作 Git 版本库 - GitPython
GitPython 是一个用于操作 Git 版本库的 python 包, 它提供了一系列的对象模型(库 - Repo.树 - Tree.提交 - Commit等) 用于操作版本库中的相应对象. 版本库 ...
- ajax 请求 后台返回的文件流
download(url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); // 也可以使用POST方式,根据接口 xhr. ...
- [洛谷P1552][APIO2012]派遣
题目大意:有一棵$n$个点的树,和一个费用$m$,每个点有一个费用和价值,请选一个点,再从它的子树中选取若干个点,使得那个点的价值乘上选的点的个数最大,要求选的点费用总和小于等于$m$ 题解:树形$d ...
- 【转】OSI详解
本文转自牛客网友CZ❤♡ღQM对在ISO/OSI参考模型中,网络层的主要功能是一题的回答. OSI ( Open System Interconnect ),即开放式系统互联. 一般都叫 OSI 参考 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 34张史上最全IT架构师技术知识图谱 最新下载
本文是笔者多年来积累和收集的知识技能图谱,小编极力推荐分享给身边的技术人儿,希望这份技术知识图谱能够帮助到每一位奋斗在技术路上的小伙伴. 下面是笔者多年来积累和收集的知识技能图谱,有的是笔者原创总结的 ...
- 【线段树】【P3372】模板-线段树
百度百科 Definition&Solution 线段树是一种log级别的树形结构,可以处理区间修改以及区间查询问题.期望情况下,复杂度为O(nlogn). 核心思想见百度百科,线段树即将每个 ...
- [ethernet]ubuntu更换网卡驱动
问题: 网络不能ping通,dmesg显示很多 [::00.0: eth0: link up [::00.0: eth0: link up [::00.0: eth0: link up [::00.0 ...
- jQuery无法获取隐藏元素(display:none)宽度(width)和高度(height)的新解决方案
用jQuery写一个通过点击左右图标来翻阅图片的小插件,写好后测试可以正常运行,但是放到Tab中后发现只有第一个Tab中的代码能够正常运行,其它全部罢工了. 用Chrome自带的开发工具一查,发现罢工 ...