http://xingzheqiang.blog.163.com/blog/static/20561012520127464654159/

背景知识不明者找Google。

-----------------------------------------------------------------------------

先简单看一下主过程://一看如此简单,先吓一跳。

int MAXFLOW(){hights();prepare();while (!Q.empty()) {u = Q.get;for each e in G' (from u) push(e);if (!fixed(u)) reCalc(u);}
}

接下来介绍算法
预流推进算法给每一个顶点一个标号h(v),表示该点到t的最短路(在残量网络中)。
第一步hights()过程,就是BFS出初始最短路,计算出每一个结点的h(v)。//可以看作是汇点有“吸力”,使每个结点有不同的负压,在“负压”作用下把来自源点的流吸过去。

预流推进算法的特征是运用了预流来加快运算。预流说明图中的结点(除s, t),仅需要满足流入量 >= 流出量。其中流入量>流出量的结点,我们称之为活动结点。/*换句话说就是有流可吸,还没吸到地方。*/我们的算法就是不断地将活动结点,变为非活动结点,使得预流成为可行流。

算法过程prepare(),即首先将与s相连的边设为满流,并将这时产生的活动结点加入队列Q。这是算法的开始。
以后便重复以下过程直到Q为空:
(1).选出Q的一个活动结点u。并依次判断残量网络G'中每条边(u, v),若h(u) = h(v) + 1,则顺着这些边推流,直到Q变成非活动结点(不存在多余流量)。(Push推流过程)//同时把所有v加入活动结点的队列。
(2).如果u还是活动结点。则需要对u进行重新标号:h(u) = min{h(v) + 1},其中边(u,v)存在于G' 中。然后再将u加入队列。(reCalc过程)//后面都满流时就吸不动了,负压自然也要重新计算。

可以证明,通过以上算法得到的结果就是最大流。

//显然每次循环后标号和残量网络都是相容的。算法结束时Q为空,只可能是没有活动结点。因为一开始就把从源所有的流推了出来,只可能是要么能够推到汇要么最后退回源。显然,一开始源的标号最高,退回源说明源汇之间已被切断,否则总能杀出一条增广路来。

如果该算法的Q是标准的FIFO队列,则时间复杂度为(n2m),/*最高标号不会超过n(超过时必无到汇的路径),所以n个点每个最多重新标号n次,两次标号之间m条边每条最多推流一次。*/如果是优先队列,并且标号最高的点优先的话,我们就得到了最高标号预流推进算法,其时间复杂度仅为(n2sqrt(m)),/*复杂度分析进行中……*/算是比较快的最大流算法了。

添加一个示例代码:

http://kenby.iteye.com/blog/945483

#include <stdio.h>
#include <string.h>#define DEBUG#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif#define N 102
#define MAX_INT 2000000#define min(a, b) ((a) < (b) ? (a) : (b))int      graph[N][N];
int     h[N];
int     e[N];
int     n;int push_relabel(int s, int t)
{int    max_flow, u, v, d, done, relabel, min_height;memset(h, 0, sizeof(h));memset(e, 0, sizeof(e));h[s] = n;for (u = 1; u <= t; u++) {if (graph[s][u] > 0) {e[u] = graph[s][u];e[s] -= graph[s][u];graph[u][s] = graph[s][u];graph[s][u] = 0;}}for (;;) {done = 1;for (u = s+1; u < t; u++) {if (e[u] > 0) {done = 0;//先假设顶点u需要relabelrelabel = 1;for (v = s; v <= t && e[u] > 0; v++) {    /* 检查能push的顶点 */if (graph[u][v] > 0 && h[u] > h[v]) {//pushrelabel = 0;d = min(graph[u][v], e[u]);e[u] -= d;e[v] += d;graph[u][v] -= d;graph[v][u] += d;debug("push %d --%d--> %d, e[%d] = %d\n", u, d, u, u, e[u]);}}//没有可以push的顶点,执行relabelif (relabel) {//relabelmin_height = MAX_INT;for (v = s; v <= t; v++) {if (graph[u][v] > 0 && h[v] < min_height) {min_height = h[v];}}h[u] = 1 + min_height;debug("relabel %d height to %d\n", u, h[u]);}}}if (done) {   /* 除源点和汇点外,每个顶点的e[i]都为0 */max_flow = 0;for (u = s; u <= t; u++) {if (graph[t][u] > 0) {max_flow += graph[t][u];}}break;}}return max_flow;
}int main()
{int        np, nc, m, u, v, w;while (scanf("%d", &n) != EOF) {n += 2;     /* 添加源点和汇点 */scanf("%d %d %d", &np, &nc, &m);memset(graph, 0, sizeof(graph));//输入m条边while (m--) {scanf(" (%d,%d)%d", &u, &v, &w);graph[u+1][v+1] = w;}//输入np个power stationwhile (np--) {scanf(" (%d)%d", &u, &w);graph[0][u+1] = w;}//输入nc个consumerwhile (nc--) {scanf(" (%d)%d", &u, &w);graph[u+1][n-1] = w;}printf("%d\n", push_relabel(0, n-1));}return 0;
}

最大流算法——预流推进相关推荐

  1. [洛谷P4722]【模板】最大流 加强版 / 预流推进

    会$TLE$... C++ Code:(HLPP) #pragma GCC optimize(3) #pragma GCC optimize("unroll-loops") #in ...

  2. 分析常见限流算法及手写三种(计数器、漏斗、令牌桶)代码实现

    常见的限流算法分析 限流在我们日常生活中经常见到,如火车站门口的栏杆.一些景点的门票只出售一定的数量 等等.在我们的开发中也用到了这种思想. 为什么要限流 在保证可用的情况下尽可能多增加进入的人数,其 ...

  3. 从Dinic到ISAP,从余流推进到最高标号的预留推进HLPP(究极最大流算法)

    题目链接--很好的一道对于网络流提升的题 Dinic 首先,这道题真的将Dinic算法卡到了它的上界,也就是,在这道题中,使用一般的Dinic最后会获得40分. #include <iostre ...

  4. 究极最大流算法(ISAP)(HLPP)

    有2个ISAP(Improved Shortest Augumenting Path),和最高标号预流推进(HLPP). Dinic 和 ISAP 都是O(n2m)O(n^2m)O(n2m),实际表现 ...

  5. 最大流算法之三:ISAP

    最大流算法之三:ISAP <转> (2009-08-14 19:24:27) 转载▼ 标签: it 分类: 理论 通常的 SAP 类算法在寻找增广路时总要先进行 BFS,BFS 的最坏情况 ...

  6. 接口限流算法:漏桶算法令牌桶算法

    工作中对外提供的API 接口设计都要考虑限流,如果不考虑限流,会成系统的连锁反应,轻者响应缓慢,重者系统宕机,整个业务线崩溃,如何应对这种情况呢,我们可以对请求进行引流或者直接拒绝等操作,保持系统的可 ...

  7. 限流算法之计数器(一)

    一.为什么需要限流 按照服务的调用方,可以分为以下几种类型服务 1.与用户打交道的服务 比如web服务.对外API,这种类型的服务有以下几种可能导致机器被拖垮: 用户增长过快(这是好事) 因为某个热点 ...

  8. 最大流算法-ISAP

    引入 最大流算法分为两类,一种是增广路算法,一种是预留推进算法.增广路算法包括时间复杂度\(O(nm^2)\)的EK算法,上界为\(O(n^2m)\)的Dinic算法,以及一些其他的算法.EK算法直接 ...

  9. 搞懂限流算法这一篇就够了

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 TL;DR(too long don't read) 限流算法:计 ...

最新文章

  1. 计算机c盘属性不显示安全选项,win7系统中文件夹属性安全选项卡空白的解决方法...
  2. 1.QML语法、属性和元素
  3. redmine 一键安装
  4. 软件工程第一周开课博客
  5. 构造函数与折构函数(c++细节篇五)
  6. Qt操作SQLite数据库练习(20200215)
  7. Java关键字synchronized的简单理解
  8. Algorithms Part 1-Question 2-QuickSort-快速排序算法
  9. mysql字符型数字 按大小排序,类似if判断函数
  10. 金字塔原理--公开演讲
  11. matlab低通滤波器库函数代码_【转】Matlab中模拟低通滤波器的函数
  12. elasticsearch使用3:配置同义词词库、ik分词器扩展字典和扩展停止词字典
  13. 第四章 政策过程及其理论模型
  14. 真题解析 | 2022数模美赛C题:股票投资策略
  15. Dictionary 索引超出数组界限
  16. idea快速查找一个类或类中方法名和变量
  17. 国产操作系统之中兴新支点NewStartOS安装
  18. 开发人员的linux操作系统Tips
  19. Hadoop:INFO mapreduce.Job: Running job
  20. 2697v3只支持服务器内存,Intel 18核心E5-2697 v4实测:虐杀桌面顶级8核i7-5960X!

热门文章

  1. 栈与堆、浅拷贝与深拷贝以及什么是闭包
  2. python写入csv指定单元格_使用python中的csv模块写入特定单元格
  3. 04-study哈尔滨理工新生赛 我太菜了
  4. 微信小程序 onReachBottom 上拉触底加载 没触发
  5. 批量关闭公众号推送_微信喊你「批量屏蔽公众号」啦!还有其他新功能!!
  6. 国内各大厂ChatGPT技术布局及应用场景
  7. 实现二叉树先序,中序和后序遍历
  8. 0427-市场多头的一天,马来西亚棕榈油涨停
  9. 从一棵“微博树”透视物联网的未来
  10. 在学校表中分别显示各个学校的教师和学生人数,查询总数