HLPP算法 一种高效的网络最大流算法
- #include <algorithm>
- #include <cstdio>
- #include <cctype>
- #include <queue>
- #define INF 0x3f3f3f3f
- #define MAXN 10010
- #define MAXM 300010
- using namespace std;
- int n, m, s, t, tot = ;
- int beginx[MAXN], endx[MAXM], nxt[MAXM], res[MAXM];
- inline void add_edge(int u, int v, int w)
- {
- nxt[++tot] = beginx[u], beginx[u] = tot, endx[tot] = v, res[tot] = w;
- nxt[++tot] = beginx[v], beginx[v] = tot, endx[tot] = u, res[tot] = ;
- }
- struct PQ
- {
- int x,h;
- PQ(int _x,int _h)
- {
- x = _x, h = _h;
- }
- bool operator < (const PQ &tar) const
- {
- return h < tar.h;
- }
- };
- int gap[MAXN], d[MAXN], ans[MAXN];
- inline bool push(int x, int y, int ptr)
- {
- int w = min(ans[x], res[ptr]);
- res[ptr] -= w, res[ptr^] += w;
- ans[x] -= w, ans[y] += w;
- return w;
- }
- inline void Gap(int val)
- {
- for (int i = ; i <= n; ++i)
- if(i != s && i != t && val < d[i] && d[i] <= n)
- d[i] = n + ;
- }
- inline int HLPP()
- {
- priority_queue<PQ> pq;
- d[s] = n, ans[s] = INF, pq.push(PQ(s, d[s]));
- int u;
- while(!pq.empty())
- {
- u = pq.top().x, pq.pop();
- if(!ans[u]) continue;
- for(int i = beginx[u], v = endx[i]; i; i = nxt[i], v = endx[i])
- if((u == s || d[u] == d[v] + ) && push(u, v, i) && v != t && v != s)
- pq.push(PQ(v, d[v]));
- if (u != s && u != t && ans[u])
- {
- if(!(--gap[d[u]])) Gap(d[u]);
- ++gap[++d[u]];
- pq.push(PQ(u, d[u]));
- }
- }
- return ans[t];
- }
- int main()
- {
- scanf("%d%d%d%d",&n,&m,&s,&t);
- for(int i = ; i <= m; i++)
- {
- int u,v,r;
- scanf("%d%d%d",&u,&v,&r);
- add_edge(u, v, r);
- }
- printf("%d", HLPP());
- return ;
- }
HLPP
主程序仅有35行,可能会TLE,需要卡卡常数。
暴露出的问题:
- priority_queue太慢,用pq比普通队列还慢。
- STL效率差到爆炸,明明是需要多次BFS,入队出队次数很多,然而效率低,没办法,卡死了。
- #include <cstdio>
- #include <cctype>
- using namespace std;
- #define MAXN 10005
- #define MAXM 200010
- #define INF 0x3f3f3f3f
- inline char get_char()
- {
- static char buf[], *p1 = buf, *p2 = buf;
- return p1 == p2 && (p2 = (p1 = buf) + fread(buf, , , stdin), p1 == p2) ? EOF : *p1 ++;
- }
- inline int read()
- {
- register int num = ;
- char c;
- while (isspace(c = get_char()));
- while (num = num * + c - , isdigit(c = get_char()));
- return num;
- }
- inline void upmin(int &a, const int &b)
- {
- if(a > b) a = b;
- }
- int beginx[MAXN], endx[MAXM], nxt[MAXM], res[MAXM];
- struct Q
- {
- int s, t;
- Q()
- {
- s = , t = ;
- }
- int q[MAXM];
- inline bool empty()
- {
- return s > t;
- }
- inline int front()
- {
- return q[s++];
- }
- inline void push(int tar)
- {
- q[++t] = tar;
- }
- } mession;
- int main()
- {
- register int n = read(), m = read(), s = read(), t = read(), tot = ;
- for(int i = ; i <= m; i++)
- {
- int u = read(), v = read(), c = read();
- nxt[++tot] = beginx[u], beginx[u] = tot, endx[tot] = v, res[tot] = c;
- nxt[++tot] = beginx[v], beginx[v] = tot, endx[tot] = u, res[tot] = ;
- }
- register int ar = s, r = INF, ans = ;
- bool done;
- int d[MAXN], num[MAXN], cur[MAXN], pre[MAXN];
- mession.push(t);
- d[t] = ;
- register int u, v;
- while(!mession.empty())
- {
- u = mession.front();
- num[d[u]]++;
- for(int i = beginx[u]; i; i = nxt[i])
- {
- v = endx[i];
- if(!d[v] && res[i ^ ])
- {
- d[v] = d[u] + ;
- mession.push(v);
- }
- }
- }
- for(int i = ; i <= n; i++) cur[i] = beginx[i];
- while(d[s] != n + )
- {
- if(ar == t)
- {
- while(ar != s)
- {
- res[pre[ar]] -= r, res[pre[ar] ^ ] += r;
- ar = endx[pre[ar] ^ ];
- }
- ans += r, r = INF;
- }
- done = false;
- for(int &i = cur[ar]; i; i = nxt[i])
- {
- int v = endx[i];
- if(res[i] && d[v] == d[ar] - )
- {
- done = true, pre[v] = i, ar = v;
- upmin(r, res[i]);
- break;
- }
- }
- if(!done)
- {
- register int heig = n + ;
- for(int i = beginx[ar]; i; i = nxt[i])
- {
- int v = endx[i];
- if(res[i]) upmin(heig, d[v] + );
- }
- if(--num[d[ar]] == ) break;
- cur[ar] = beginx[ar];
- num[d[ar] = heig]++;
- if(ar != s) ar = endx[pre[ar] ^ ];
- }
- }
- printf("%d", ans);
- return ;
- }
HLPP算法 一种高效的网络最大流算法的更多相关文章
- 网络最大流算法—EK算法
前言 EK算法是求网络最大流的最基础的算法,也是比较好理解的一种算法,利用它可以解决绝大多数最大流问题. 但是受到时间复杂度的限制,这种算法常常有TLE的风险 思想 还记得我们在介绍最大流的时候提到的 ...
- 网络最大流算法—Dinic算法及优化
前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. ...
- 网络最大流算法—最高标号预流推进HLPP
吐槽 这个算法.. 怎么说........ 学来也就是装装13吧.... 长得比EK丑 跑的比EK慢 写着比EK难 思想 大家先来猜一下这个算法的思想吧:joy: 看看人家的名字——最高标号预留推进 ...
- 算法9-5:最大流算法的Java代码
残留网络 在介绍最大流算法之前先介绍一下什么是残留网络.残余网络的概念有点类似于集合中的补集概念. 下图是残余网络的样例. 上面的网络是原始网络.以下的网络是计算出的残留网络.残留网络的作用就是用来描 ...
- [学习笔记] 网络最大流的HLPP算法
#define \(u\)的伴点集合 与\(u\)相隔一条边的且\(u\)能达到的点的集合 \(0x00~ {}~Preface\) \(HLPP(Highest~Label~Preflow~Push ...
- 使用JavaScript进行数组去重——一种高效的算法
最近比较忙,没时间更新博客,等忙完这阵子会整理一篇使用AngularJS构建一个中型的单页面应用(SPA)的文章,尽情期待!先占个坑. 数组去重的算法有很多种,以下是一种. 思路如下: 定义一个空的对 ...
- 神经网络训练中的Tricks之高效BP(反向传播算法)
神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...
- 最大流算法-最高标号预流推进(HLPP)
昨天我们学习了ISAP算法,它属于增广路算法的大类.今天学习的算法是预流推进算法中很高效的一类--最高标号预流推进(HLPP). 预流推进 预流推进是一种很直观的网络流算法.如果给到一个网络流让你手算 ...
- larbin是一种开源的网络爬虫/网络蜘
larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发.larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源.Lar ...
随机推荐
- Codeforces Round #306 (Div. 2) D
D. Regular Bridge time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- TRIZ的成功案例
这篇採訪稿是几年前的,是TRIZ成功案例离我近期的,由于主人公是我的朋友,请点击查看: 培训后技术难题就攻克了 后记:学了TRIZ并不能让您100%解决您全部遇到的问题,但这样的思想和方法确实是最具操 ...
- java Regex
超全 http://www.rexegg.com/regex-lookarounds.html 这篇文章不错:http://www.cnblogs.com/lzq198754/p/5780340.ht ...
- HDU 3656 二分+dlx判定
Fire station Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- HDU 4099 Revenge of Fibonacci Trie+高精度
Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...
- 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 ...
- App/Activity/Screen Orientation
测试android屏幕方向的小Demo 1.首先我们在values下面新建文件arrays.xml(用来在下拉列表中显示) <?xml version="1.0" encod ...
- curses-键盘编码-openssl加解密【转】
本文转载自;https://zhuanlan.zhihu.com/p/26164115 1.1 键盘编码 按键过程:当用户按下某个键时, 1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan ...
- hdoj--5625--Clarke and chemistry(枚举)
Clarke and chemistry Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- Linux下查看操作系统的位数和系统名称版本信息
Linux下如何明确地查看操作系统的位数 如何知晓操作系统是32位还是64位?这里介绍一种简单的方式: [plain] [root@localhost mysql-5.1.57]# getconf L ...