#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算法 一种高效的网络最大流算法的更多相关文章

  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. HIHO 16 C

    树分治.对于一棵子树的根节点,至少有一条边与儿子相连的属于重边.对于一条轻边,它的贡献值是两端子树大小的乘积,所以,重边应该是贡献值最大的一边. 至于要求所有的点,进行深度优先搜索,因为移动一个点只会 ...

  2. Extjs 3 控制Grid某行某列不可编辑

    var cmGoodsFee = new Ext.grid.ColumnModel([rmGoodsFee, { header : "id", tooltip : "id ...

  3. luogu2341 [HAOI2006]受欢迎的牛

    题目大意 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜欢B,B喜欢C,那么A也喜欢C.牛 ...

  4. C++中的inline的用法

    C++中的inline的用法  参考:http://www.cnblogs.com/fnlingnzb-learner/p/6423917.html 1. 引入inline关键字的原因 在c/c++中 ...

  5. C# Path 有关于文件路径获取的问题 的方法

    string Current = Directory.GetCurrentDirectory();//获取当前根目录 //private string strFilePath = Applicatio ...

  6. mongodb 对内存的占用监控 ——mongostat,linux系统可用的内存是free + buffers + cached

    刚开始使用mongodb的时候,不太注意mongodb的内存使用,但通过查资料发现mongodb对内存的占用是巨大的,在本地测试服务器中,8G的内存居然被占用了45%.汗呀. 本文就来剖析一下mong ...

  7. B1922 [Sdoi2010]大陆争霸 最短路

    我一直都不会dij的堆优化,今天搞了一下...就是先弄一个优先队列,存每个点的数据,然后这个题就加了一点不一样的东西,每次的最短路算两次,一次是自己的最短路,另一次是机关的最短路,两者取最大值才是该点 ...

  8. B1800 [Ahoi2009]fly 飞行棋 数学模拟

    20分钟一遍AC,大水题,我的算法比较复杂,但是好理解,就是找可以凑出来一半周长的点来暴力枚举就行了. 题干: Description 给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依 ...

  9. Highways(prim)

    http://poj.org/problem?id=2485 此题是求最小生成树里的最大权值.prim算法: #include<stdio.h> #include<string.h& ...

  10. 通过JS制作一个简易数码时钟

    设计思路: 数码时钟即通过图片数字来显示当前时间,需要显示的图片的URL根据时间变化而变化. a.获取当前时间Date()并将当前时间信息转换为一个6位的字符串; b.根据时间字符串每个位置对应的数字 ...