1. #include <algorithm>
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <queue>
  5. #define INF 0x3f3f3f3f
  6. #define MAXN 10010
  7. #define MAXM 300010
  8. using namespace std;
  9. int n, m, s, t, tot = ;
  10. int beginx[MAXN], endx[MAXM], nxt[MAXM], res[MAXM];
  11. inline void add_edge(int u, int v, int w)
  12. {
  13. nxt[++tot] = beginx[u], beginx[u] = tot, endx[tot] = v, res[tot] = w;
  14. nxt[++tot] = beginx[v], beginx[v] = tot, endx[tot] = u, res[tot] = ;
  15. }
  16. struct PQ
  17. {
  18. int x,h;
  19. PQ(int _x,int _h)
  20. {
  21. x = _x, h = _h;
  22. }
  23. bool operator < (const PQ &tar) const
  24. {
  25. return h < tar.h;
  26. }
  27. };
  28. int gap[MAXN], d[MAXN], ans[MAXN];
  29. inline bool push(int x, int y, int ptr)
  30. {
  31. int w = min(ans[x], res[ptr]);
  32. res[ptr] -= w, res[ptr^] += w;
  33. ans[x] -= w, ans[y] += w;
  34. return w;
  35. }
  36. inline void Gap(int val)
  37. {
  38. for (int i = ; i <= n; ++i)
  39. if(i != s && i != t && val < d[i] && d[i] <= n)
  40. d[i] = n + ;
  41. }
  42. inline int HLPP()
  43. {
  44. priority_queue<PQ> pq;
  45. d[s] = n, ans[s] = INF, pq.push(PQ(s, d[s]));
  46. int u;
  47. while(!pq.empty())
  48. {
  49. u = pq.top().x, pq.pop();
  50. if(!ans[u]) continue;
  51. for(int i = beginx[u], v = endx[i]; i; i = nxt[i], v = endx[i])
  52. if((u == s || d[u] == d[v] + ) && push(u, v, i) && v != t && v != s)
  53. pq.push(PQ(v, d[v]));
  54. if (u != s && u != t && ans[u])
  55. {
  56. if(!(--gap[d[u]])) Gap(d[u]);
  57. ++gap[++d[u]];
  58. pq.push(PQ(u, d[u]));
  59. }
  60. }
  61. return ans[t];
  62. }
  63. int main()
  64. {
  65. scanf("%d%d%d%d",&n,&m,&s,&t);
  66. for(int i = ; i <= m; i++)
  67. {
  68. int u,v,r;
  69. scanf("%d%d%d",&u,&v,&r);
  70. add_edge(u, v, r);
  71. }
  72. printf("%d", HLPP());
  73. return ;
  74. }

HLPP

主程序仅有35行,可能会TLE,需要卡卡常数。

暴露出的问题:

- priority_queue太慢,用pq比普通队列还慢。

- STL效率差到爆炸,明明是需要多次BFS,入队出队次数很多,然而效率低,没办法,卡死了。

  1. #include <cstdio>
  2. #include <cctype>
  3. using namespace std;
  4. #define MAXN 10005
  5. #define MAXM 200010
  6. #define INF 0x3f3f3f3f
  7.  
  8. inline char get_char()
  9. {
  10. static char buf[], *p1 = buf, *p2 = buf;
  11. return p1 == p2 && (p2 = (p1 = buf) + fread(buf, , , stdin), p1 == p2) ? EOF : *p1 ++;
  12. }
  13. inline int read()
  14. {
  15. register int num = ;
  16. char c;
  17. while (isspace(c = get_char()));
  18. while (num = num * + c - , isdigit(c = get_char()));
  19. return num;
  20. }
  21. inline void upmin(int &a, const int &b)
  22. {
  23. if(a > b) a = b;
  24. }
  25.  
  26. int beginx[MAXN], endx[MAXM], nxt[MAXM], res[MAXM];
  27.  
  28. struct Q
  29. {
  30. int s, t;
  31. Q()
  32. {
  33. s = , t = ;
  34. }
  35. int q[MAXM];
  36. inline bool empty()
  37. {
  38. return s > t;
  39. }
  40. inline int front()
  41. {
  42. return q[s++];
  43. }
  44. inline void push(int tar)
  45. {
  46. q[++t] = tar;
  47. }
  48. } mession;
  49.  
  50. int main()
  51. {
  52. register int n = read(), m = read(), s = read(), t = read(), tot = ;
  53. for(int i = ; i <= m; i++)
  54. {
  55. int u = read(), v = read(), c = read();
  56. nxt[++tot] = beginx[u], beginx[u] = tot, endx[tot] = v, res[tot] = c;
  57. nxt[++tot] = beginx[v], beginx[v] = tot, endx[tot] = u, res[tot] = ;
  58. }
  59. register int ar = s, r = INF, ans = ;
  60. bool done;
  61. int d[MAXN], num[MAXN], cur[MAXN], pre[MAXN];
  62. mession.push(t);
  63. d[t] = ;
  64. register int u, v;
  65. while(!mession.empty())
  66. {
  67. u = mession.front();
  68. num[d[u]]++;
  69. for(int i = beginx[u]; i; i = nxt[i])
  70. {
  71. v = endx[i];
  72. if(!d[v] && res[i ^ ])
  73. {
  74. d[v] = d[u] + ;
  75. mession.push(v);
  76. }
  77. }
  78. }
  79. for(int i = ; i <= n; i++) cur[i] = beginx[i];
  80. while(d[s] != n + )
  81. {
  82. if(ar == t)
  83. {
  84. while(ar != s)
  85. {
  86. res[pre[ar]] -= r, res[pre[ar] ^ ] += r;
  87. ar = endx[pre[ar] ^ ];
  88. }
  89. ans += r, r = INF;
  90. }
  91. done = false;
  92. for(int &i = cur[ar]; i; i = nxt[i])
  93. {
  94. int v = endx[i];
  95. if(res[i] && d[v] == d[ar] - )
  96. {
  97. done = true, pre[v] = i, ar = v;
  98. upmin(r, res[i]);
  99. break;
  100. }
  101. }
  102. if(!done)
  103. {
  104. register int heig = n + ;
  105. for(int i = beginx[ar]; i; i = nxt[i])
  106. {
  107. int v = endx[i];
  108. if(res[i]) upmin(heig, d[v] + );
  109. }
  110. if(--num[d[ar]] == ) break;
  111. cur[ar] = beginx[ar];
  112. num[d[ar] = heig]++;
  113. if(ar != s) ar = endx[pre[ar] ^ ];
  114. }
  115. }
  116. printf("%d", ans);
  117. return ;
  118. }

HLPP算法 一种高效的网络最大流算法的更多相关文章

  1. 网络最大流算法—EK算法

    前言 EK算法是求网络最大流的最基础的算法,也是比较好理解的一种算法,利用它可以解决绝大多数最大流问题. 但是受到时间复杂度的限制,这种算法常常有TLE的风险 思想 还记得我们在介绍最大流的时候提到的 ...

  2. 网络最大流算法—Dinic算法及优化

    前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. ...

  3. 网络最大流算法—最高标号预流推进HLPP

    吐槽 这个算法.. 怎么说........ 学来也就是装装13吧.... 长得比EK丑 跑的比EK慢 写着比EK难 思想 大家先来猜一下这个算法的思想吧:joy: 看看人家的名字——最高标号预留推进 ...

  4. 算法9-5:最大流算法的Java代码

    残留网络 在介绍最大流算法之前先介绍一下什么是残留网络.残余网络的概念有点类似于集合中的补集概念. 下图是残余网络的样例. 上面的网络是原始网络.以下的网络是计算出的残留网络.残留网络的作用就是用来描 ...

  5. [学习笔记] 网络最大流的HLPP算法

    #define \(u\)的伴点集合 与\(u\)相隔一条边的且\(u\)能达到的点的集合 \(0x00~ {}~Preface\) \(HLPP(Highest~Label~Preflow~Push ...

  6. 使用JavaScript进行数组去重——一种高效的算法

    最近比较忙,没时间更新博客,等忙完这阵子会整理一篇使用AngularJS构建一个中型的单页面应用(SPA)的文章,尽情期待!先占个坑. 数组去重的算法有很多种,以下是一种. 思路如下: 定义一个空的对 ...

  7. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  8. 最大流算法-最高标号预流推进(HLPP)

    昨天我们学习了ISAP算法,它属于增广路算法的大类.今天学习的算法是预流推进算法中很高效的一类--最高标号预流推进(HLPP). 预流推进 预流推进是一种很直观的网络流算法.如果给到一个网络流让你手算 ...

  9. larbin是一种开源的网络爬虫/网络蜘

    larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发.larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源.Lar ...

随机推荐

  1. Codeforces Round #306 (Div. 2) D

    D. Regular Bridge time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  2. TRIZ的成功案例

    这篇採訪稿是几年前的,是TRIZ成功案例离我近期的,由于主人公是我的朋友,请点击查看: 培训后技术难题就攻克了 后记:学了TRIZ并不能让您100%解决您全部遇到的问题,但这样的思想和方法确实是最具操 ...

  3. java Regex

    超全 http://www.rexegg.com/regex-lookarounds.html 这篇文章不错:http://www.cnblogs.com/lzq198754/p/5780340.ht ...

  4. HDU 3656 二分+dlx判定

    Fire station Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  5. HDU 4099 Revenge of Fibonacci Trie+高精度

    Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...

  6. Modern Qt Development: The Top 10 Tools You Should Be Using

    Published Friday October 12th, 2018Leave a comment Posted in Biz Circuit & Dev Loop, C++, QtCrea ...

  7. App/Activity/Screen Orientation

    测试android屏幕方向的小Demo 1.首先我们在values下面新建文件arrays.xml(用来在下拉列表中显示) <?xml version="1.0" encod ...

  8. curses-键盘编码-openssl加解密【转】

    本文转载自;https://zhuanlan.zhihu.com/p/26164115 1.1 键盘编码 按键过程:当用户按下某个键时, 1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan ...

  9. hdoj--5625--Clarke and chemistry(枚举)

    Clarke and chemistry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  10. Linux下查看操作系统的位数和系统名称版本信息

    Linux下如何明确地查看操作系统的位数 如何知晓操作系统是32位还是64位?这里介绍一种简单的方式: [plain] [root@localhost mysql-5.1.57]# getconf L ...