所谓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费用流的更多相关文章

  1. 图论-zkw费用流

    图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...

  2. zkw费用流+当前弧优化

    zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...

  3. zkw费用流

    期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...

  4. 【zkw费用流】[网络流24题]餐巾计划问题

    题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...

  5. CSU 1948: 超级管理员(普通费用流&&zkw费用流)

    Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...

  6. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...

  7. zkw费用流 学习笔记

    分析 记\(D_i\)为从\(S\)出发到\(i\)的最短路 最短路算法保证, 算法结束时 对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ① 且对于每个 \(j\ ...

  8. P4015 运输问题【zkw费用流】

    输入输出样例 输入 #1复制 2 3 220 280 170 120 210 77 39 105 150 186 122 输出 #1复制 48500 69140zuixiaofeiyo 说明/提示 1 ...

  9. HDU 4744 Starloop System(ZKW费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4744 题意:三维空间n个点,每个点有一个wi值.每对点的距离定义为floor(欧拉距离),每对点之间建 ...

随机推荐

  1. 谷歌、百度、1万ip能赚多少钱?1000IP能够值多少钱呢?

    谷歌.百度.1万ip能赚多少钱?1000IP能够值多少钱呢? (2014-04-03 11:50:52) 转载▼ 标签: 广告联盟 百度联盟 谷歌联盟 ip赚钱       很多在人问:谷歌.百度:1 ...

  2. codeforces B. Simple Molecules 解题报告

    题目链接:http://codeforces.com/problemset/problem/344/B 题目意思:这句话是解题的关键: The number of bonds of an atom i ...

  3. 使用apktool工具遇到could not decode arsc file的解决办法

    问题详情: 当前环境为 win7 64位  jdk1.7  apktool.jar(版本1.5.2)   apktool(版本windows-r05-ibot) 使用的反编译工具和apk文件为 反编译 ...

  4. HTML标签自定义属性(转)

    HTML标签可以自定义属性 HTML标签可以自定义属性,但是我们要考虑其在IE.Firefox以及chrome下的兼容性问题.例如: <div id="newTest" my ...

  5. linux_command_撷叏命令: cut, grep

    [root@www ~]# cut -d'分隑字符' -f fields <==用亍有特定分隑字符[root@www ~]# cut -c 字符区间<==用亍排列整齐癿讯息选项不参数:-d ...

  6. [hihoCoder] 博弈游戏·Nim游戏

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob.Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏.在 ...

  7. Quartus 软件的使用之PLL的使用

    练习使用Altera FPGA 内的 PLL IP核: 思路:将clk_50M倍频到clk_100M,然后观察100M时钟. 1.生成PLL的核例化文件,然后调用. 点击NEXT之后,等一会会跳出如下 ...

  8. index index.html index.htm index.php

    server { listen 80; server_name localhost; index index.html index.htm index.php;#前后顺序有关系,越在前优先级别越高 r ...

  9. PIGOSS

    http://blog.sina.com.cn/s/blog_865bc4c60102wkb1.html

  10. 【bzoj1051】 [HAOI2006]受欢迎的牛 tarjan缩点判出度算点数

    [bzoj1051] [HAOI2006]受欢迎的牛 2014年1月8日7450 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B ...