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 #303 (Div. 2) E
五道水题,但要手快才好...我手慢了,E题目都没看完TAT.... 想了一发,很水,就是一遍Dijk即可,使用优先队列,同时记录由哪条边转移而来 #include <iostream> # ...
- [PWA] Show Notifications when a Service Worker is Installed or Updated
Service Workers get installed and activated in the background, but until we reload the page they don ...
- 基于Windows Azure 安装 SharePoint 2010简体中文语言包
在Windows Azure上安装的Windows Server默认是英文版本的,当时安装的SharePoint也是英文版的,为方便使用,决定安装中文的语言包,具体过程如下: 1. 安装 Window ...
- 关于isset的一点说明
作者:zhanhailiang 日期:2014-10-08 今天遇到一个非常奇怪的bug,測试例如以下: <? php $a = 'abc'; var_dump(isset($a['code'] ...
- Ant报错之out of memory
用Ant打包一个比較大的项目的时候,遇到OutOfMemory的问题,求助于Google和百度,网上的解决方式非常多,可是个人认为不够具体全面.我的问题须要综合两种方法才解决.把方案记下来.以期帮助大 ...
- iOS - 社会化分享-微信分享,朋友圈分享
我仅仅做了文字和图片分享功能 1. TARGETS - Info - URL Types identifier -> weixin URL Schemes -> 应用id 2.在AppD ...
- C\C++控制台颜色设置类
windows和Linux都可用的一个类...用来设置颜色,没有太复杂.简单够用吧. #ifdef _WIN32 #include <Windows.h> class FontColor ...
- 如何运行开源的React Native项目?
如何运行开源的RN项目? 1.下载 2.解压 3.配置本地sdk位置 sdk.dir = D\:\\Android\\SDK 4.调整gradle版本 apply plugin: "com. ...
- bzoj2935 [Poi1999]原始生物——欧拉回路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2935 考察欧拉回路性质的题目呢: TJ:https://blog.csdn.net/u014 ...
- insufficient space