学习了ZKW费用流
所谓ZKW费用流,其实就是Dinic。
若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2)
然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^2m)
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int inf=1e9;
const int maxn=;
const int maxm=;
struct Dinic {
int n,m,s,t;
int d[maxn],vis[maxn],first[maxn],cur[maxn],next[maxm];
struct Edge {int from,to,flow;}edges[maxm];
Dinic() {
m=;
memset(first,-,sizeof(first));
}
void AddEdge(int from,int to,int cap) {
edges[m]=(Edge){from,to,cap};next[m]=first[from];first[from]=m++;
edges[m]=(Edge){to,from,};next[m]=first[to];first[to]=m++;
}
int BFS() {
memset(vis,,sizeof(vis));
queue<int> Q;Q.push(s);d[s]=;vis[s]=;
while(!Q.empty()) {
int x=Q.front();Q.pop();cur[x]=first[x];
ren {
Edge& e=edges[i];
if(e.flow&&!vis[e.to]) vis[e.to]=,d[e.to]=d[x]+,Q.push(e.to);
}
}
return vis[t];
}
int DFS(int x,int a) {
if(x==t||!a) return a;
int flow=,f;
for(int& i=cur[x];i!=-;i=next[i]) {
Edge& e=edges[i];
if(d[e.to]==d[x]+&&(f=DFS(e.to,min(e.flow,a)))) {
e.flow-=f;edges[i^].flow+=f;
a-=f;flow+=f;if(!a) break;
}
}
return flow;
}
int solve(int s,int t) {
this->s=s;this->t=t;int ans=;
while(BFS()) ans+=DFS(s,inf);
return ans;
}
}sol;
int main() {
int n=read(),m=read();
rep(,m) {
int a=read(),b=read(),c=read();
sol.AddEdge(a,b,c);
}
printf("%d\n",sol.solve(,n));
return ;
}
于是可以用到费用流里来:我们为什么不可以在s到t最短路不变时多路增广呢?
实现做法要从t逆向做SPFA,然后多路增广,具体可以见代码
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int inf=1e9;
const int maxn=;
const int maxm=;
struct ZKW {
int n,m,s,t,cost,ans;
int d[maxn],vis[maxn],first[maxn],inq[maxn],next[maxm];
struct Edge {int from,to,flow,cost;}edges[maxm];
void init(int n) {
this->n=n;m=;
memset(first,-,sizeof(first));
memset(inq,,sizeof(inq));
}
void AddEdge(int from,int to,int cap,int cost) {
edges[m]=(Edge){from,to,cap,cost};next[m]=first[from];first[from]=m++;
edges[m]=(Edge){to,from,,-cost};next[m]=first[to];first[to]=m++;
}
int BFS() {
rep(,n) d[i]=inf;
queue<int> Q;Q.push(t);d[t]=;
while(!Q.empty()) {
int x=Q.front();Q.pop();inq[x]=;
ren {
Edge& e=edges[i^];
if(e.flow&&d[e.from]>d[x]+e.cost) {
d[e.from]=d[x]+e.cost;
if(!inq[e.from]) inq[e.from]=,Q.push(e.from);
}
}
}
rep(,m) edges[i].cost+=d[edges[i].to]-d[edges[i].from];
cost+=d[s];return d[s]!=inf;
}
int DFS(int x,int a) {
if(x==t||!a) {ans+=cost*a;return a;}
int flow=,f;vis[x]=;
ren {
Edge& e=edges[i];
if(e.flow&&!e.cost&&!vis[e.to]&&(f=DFS(e.to,min(e.flow,a)))) {
e.flow-=f;edges[i^].flow+=f;
a-=f;flow+=f;if(!a) break;
}
}
return flow;
}
int solve(int s,int t) {
this->s=s;this->t=t;ans=cost=;
while(BFS()) do memset(vis,,sizeof(vis));while(DFS(s,inf));
return ans;
}
}sol;
int main() {
int n=read(),m=read();sol.init(n);
rep(,m) {
int a=read(),b=read(),c=read(),d=read();
sol.AddEdge(a,b,c,d);
}
printf("%d\n",sol.solve(,n));
return ;
}
学习了ZKW费用流的更多相关文章
- 图论-zkw费用流
图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...
- zkw费用流+当前弧优化
zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...
- zkw费用流
期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...
- 【zkw费用流】[网络流24题]餐巾计划问题
题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...
- CSU 1948: 超级管理员(普通费用流&&zkw费用流)
Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...
- BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流
https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...
- zkw费用流 学习笔记
分析 记\(D_i\)为从\(S\)出发到\(i\)的最短路 最短路算法保证, 算法结束时 对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ① 且对于每个 \(j\ ...
- P4015 运输问题【zkw费用流】
输入输出样例 输入 #1复制 2 3 220 280 170 120 210 77 39 105 150 186 122 输出 #1复制 48500 69140zuixiaofeiyo 说明/提示 1 ...
- HDU 4744 Starloop System(ZKW费用流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4744 题意:三维空间n个点,每个点有一个wi值.每对点的距离定义为floor(欧拉距离),每对点之间建 ...
随机推荐
- http协议学习系列
深入理解HTTP协议(转) http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列 1. 基础概念篇 1.1 介绍 H ...
- java调用matlab函数
如何将实验结果在matlab中可视化呢,下面使用java语言编程,调用matlab中的函数: 本人安装的是Matlab7.11.0 (R2010a)和 Eclipse 4.2 : 1)首先设置环境变量 ...
- 理解和解决MySQL乱码问题
本文将详细介绍MySQL乱码的成因和具体的解决方案 在阅读本文之前,强烈建议对字符集编码概念还比较模糊的同学 阅读下博主之前对相关概念的一篇科普:十分钟搞清字符集和字符编码 MySQL出现乱码的原因 ...
- linux(Ubuntu)安装QQ2013
首先简述自己的系统配置:win7+ ubuntu12.04 linuxQQ 有各种版本,这里介绍两种:linuxQQ 和 wineQQ 1 ------linuxqq是QQ简化版,功能很少,界面很差, ...
- 使用wkhtmltopdf实现HTML转PDF的解决方案
最近,项目需要将HTML页面转换为PDF文件,所以就研究了下HTML转PDF的解决方案,发现网上比较流行的解决方案有3种: (1)iText (2)Flying Saucer (3)wkhtmltop ...
- eclipse 切换svn账号
1. 查看你的Eclipse中使用的是什么SVN Interface,位置在 windows > preference > Team > SVN 2. 如果是用的J ...
- DbHelper-SQL数据库访问助手
using System; using System.Data; using System.Data.SqlClient; namespace Whir.Software.Framework.Ulti ...
- FFmpeg源代码结构图
转自:http://blog.csdn.net/leixiaohua1020/article/details/44220151 FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码 ...
- C++Premer Plus学习(五)——函数探幽
一.内联函数 1.优点: 内联函数就是比较省资源,然后一般就是将简短,使用频率高的函数作为内联函数会比较合适. 2.一个demo #include "stdafx.h" #incl ...
- SQL Server:查询当前服务器有多少连接请求
有时DBA需要检查当前服务器有多少连接请求,以及连接请求的登录名,客户端版本,主机名,程序名等等之类的信息,我们就可以对服务器的连接状况有所了解,防止不明用户使用. SQL Server本身提供了这么 ...