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 ...
随机推荐
- Unity3d-反编译C#和提取资源
使用MonoDevelop查看代码 1.解压缩一个Ipa文件,找到如下目录 2.拖拽一个Assembly-CSharp.dll文件到MonoDevelop工具栏,即可查看C#代码 其他C#反编译工具: ...
- SSH整合开发时Scope为默认时现象与原理
1.前提知识 1)scope默认值 进行SSH整合开发时,Struts2的action须要用spring容器进行管理,仅仅要涉及到类以bean的形式入到spring容器中.无论是xml配置还是使用注解 ...
- ubuntu 关于sublime text3的一些应用
安装 如今能够通过ppa的方法来安装sublime text3 了,个人感觉就是有有点儿慢,毕竟要update一下. sudo add-apt-repository ppa:webupd8team/s ...
- IIS发布后出现“如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题”错误
VS2010运行程序没有任何问题,但是发布到IIS以后,连接数据库时报错:“尝试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Oracle ...
- bzoj 1191 [ HNOI 2006 ] 超级英雄Hero —— 二分图匹配
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1191 就是二分图匹配的裸题: 注意题目要求是第一次匹配失败就退出!没仔细看题差点丢失1A. ...
- DCloud-MUI:utils
ylbtech-DCloud-MUI:utils 1.返回顶部 1.init mui框架将很多功能配置都集中在mui.init方法中,要使用某项功能,只需要在mui.init方法中完成对应参数配置即可 ...
- TCP打开文件传输(服务器端并发code)
#include <stdio.h>#include <stdlib.h>#include <arpa/inet.h>#include <sys/types. ...
- LBS(定位)的使用
一.LBS(定位)的使用 1.使用框架Core Location 2.CLLocationManager (1)CoreLocation中使用CLLocationManager对象来做用户定位 (2) ...
- 关于form/input 的autocomplete="off"属性
转自:http://blog.sina.com.cn/s/blog_b49f96a701019m0d.html 一. 有过表单设计经验的朋友肯定知道,当我们在浏览器中输入表单信息的时候,往往input ...
- js实用篇之数组、字符串常用方法
常常在开发中,会使用到很多js数组和字符串的处理方法,这里列举一些我常用到的一些,方便大家参考使用. 数组方面 push:向数组尾部增加内容,返回的是新数组的长度. var arr = [1,2,3] ...