博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4280 Island Transport(HLPP板子)题解
阅读量:4558 次
发布时间:2019-06-08

本文共 6321 字,大约阅读时间需要 21 分钟。

题意:

求最大流

思路:

\(1e5\)条边,偷了一个超长的\(HLPP\)板子。复杂度\(n^2 \sqrt{m}\)。但通常在随机情况下并没有isap快。

板子:

template
struct HLPP{ const int MAXN = 1e5 + 5; const T INF = 0x3f3f3f3f; struct edge{ int to, rev; T f; }; vector
adj[maxn]; deque
lst[maxn]; vector
gap[maxn]; T excess[maxn]; int highest, height[maxn], cnt[maxn], ptr[maxn], work, N; void addEdge(int u, int v, int f, bool isdirected = true){ adj[u].push_back({v, adj[v].size(), f}); adj[v].push_back({u, adj[u].size() - 1, isdirected? 0 : f}); } void clear(int n){ N = n; for(int i = 0; i <= n; i++){ adj[i].clear(), lst[i].clear(); gap[i].clear(); } } void upHeight(int v, int nh){ ++work; if(height[v] != N) --cnt[height[v]]; height[v] = nh; if(nh == N) return; cnt[nh]++, highest = nh; gap[nh].push_back(v); if(excess[v] > 0){ lst[nh].push_back(v); ++ptr[nh]; } } void glovalRelabel(int s, int t){ work = 0; fill(height, height + N + 1, N); fill(cnt, cnt + N + 1, 0); for(int i = 0; i <= highest; i++){ lst[i].clear(); gap[i].clear(); ptr[i] = 0; } height[t] = 0; queue
q({t}); while(!q.empty()){ int v = q.front(); q.pop(); for(auto &e : adj[v]) if(height[e.to] == N && adj[e.to][e.rev].f > 0){ q.push(e.to); upHeight(e.to, height[v] + 1); } highest = height[v]; } } void push(int v, edge& e){ if(excess[e.to] == 0){ lst[height[e.to]].push_back(e.to); ++ptr[height[e.to]]; } T df = min(excess[v], e.f); e.f -= df; adj[e.to][e.rev].f += df; excess[v] -= df; excess[e.to] += df; } void discharge(int v){ int nh = N; for(auto &e : adj[v]){ if(e.f > 0){ if(height[v] == height[e.to] + 1){ push(v, e); if(excess[v] <= 0) return; } else{ nh = min(nh, height[e.to] + 1); } } } if(cnt[height[v]] > 1){ upHeight(v, nh); } else{ for(int i = height[v]; i < N; i++){ for(auto j : gap[i]) upHeight(j, N); gap[i].clear(); ptr[i] = 0; } } } T hlpp(int s, int t){ fill(excess, excess + N + 1, 0); excess[s] = INF, excess[t] = -INF; glovalRelabel(s, t); for(auto &e : adj[s]) push(s, e); for(; highest >= 0; -- highest){ while(lst[highest].size()){ int v = lst[highest].back(); lst[highest].pop_back(); discharge(v); if(work > 4 * N) glovalRelabel(s, t); } } return excess[t] + INF; }};int read() { int f = 1, x = 0; char ch = getchar(); while(! isdigit(ch)) {if(ch == '-' ) f = -f; ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();} return x * f;}HLPP
hlpp;//hlpp.clear(n)

代码:

#include 
#include
#include
#include
#include
#include
#include
#define isdigit(a) (a>='0' && a<='9')typedef long long LL;using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 2e5+5;template
struct HLPP{ const int MAXN = 1e5 + 5; const T INF = 0x3f3f3f3f; struct edge{ int to, rev; T f; }; vector
adj[maxn]; deque
lst[maxn]; vector
gap[maxn]; T excess[maxn]; int highest, height[maxn], cnt[maxn], ptr[maxn], work, N; void addEdge(int u, int v, int f, bool isdirected = true){ adj[u].push_back({v, adj[v].size(), f}); adj[v].push_back({u, adj[u].size() - 1, isdirected? 0 : f}); } void clear(int n){ N = n; for(int i = 0; i <= n; i++){ adj[i].clear(), lst[i].clear(); gap[i].clear(); } } void upHeight(int v, int nh){ ++work; if(height[v] != N) --cnt[height[v]]; height[v] = nh; if(nh == N) return; cnt[nh]++, highest = nh; gap[nh].push_back(v); if(excess[v] > 0){ lst[nh].push_back(v); ++ptr[nh]; } } void glovalRelabel(int s, int t){ work = 0; fill(height, height + N + 1, N); fill(cnt, cnt + N + 1, 0); for(int i = 0; i <= highest; i++){ lst[i].clear(); gap[i].clear(); ptr[i] = 0; } height[t] = 0; queue
q({t}); while(!q.empty()){ int v = q.front(); q.pop(); for(auto &e : adj[v]) if(height[e.to] == N && adj[e.to][e.rev].f > 0){ q.push(e.to); upHeight(e.to, height[v] + 1); } highest = height[v]; } } void push(int v, edge& e){ if(excess[e.to] == 0){ lst[height[e.to]].push_back(e.to); ++ptr[height[e.to]]; } T df = min(excess[v], e.f); e.f -= df; adj[e.to][e.rev].f += df; excess[v] -= df; excess[e.to] += df; } void discharge(int v){ int nh = N; for(auto &e : adj[v]){ if(e.f > 0){ if(height[v] == height[e.to] + 1){ push(v, e); if(excess[v] <= 0) return; } else{ nh = min(nh, height[e.to] + 1); } } } if(cnt[height[v]] > 1){ upHeight(v, nh); } else{ for(int i = height[v]; i < N; i++){ for(auto j : gap[i]) upHeight(j, N); gap[i].clear(); ptr[i] = 0; } } } T hlpp(int s, int t){ fill(excess, excess + N + 1, 0); excess[s] = INF, excess[t] = -INF; glovalRelabel(s, t); for(auto &e : adj[s]) push(s, e); for(; highest >= 0; -- highest){ while(lst[highest].size()){ int v = lst[highest].back(); lst[highest].pop_back(); discharge(v); if(work > 4 * N) glovalRelabel(s, t); } } return excess[t] + INF; }};int read() { int f = 1, x = 0; char ch = getchar(); while(! isdigit(ch)) {if(ch == '-' ) f = -f; ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();} return x * f;}HLPP
hlpp;int main() { int T; scanf("%d", &T); while(T--) { int n, m; scanf("%d%d", &n, &m); int x, y, s, t; int startX = inf, endX = -inf; for(int i = 1; i <= n; ++i) { x = read(), y = read(); if(x < startX) s = i, startX = x; if(x > endX) t = i, endX = x; } int u, v, f; hlpp.clear(n); for(int i = 1; i <= m; ++i) { u = read(), v = read(), f = read(); hlpp.addEdge(u, v, f, false); } printf("%d\n", hlpp.hlpp(s, t)); } return 0;}

转载于:https://www.cnblogs.com/KirinSB/p/11329288.html

你可能感兴趣的文章
tarroni music
查看>>
unity 使用RotateAround的使用注意
查看>>
[SDOI2009]HH的项链
查看>>
CodeFirst模式,容易引发数据迁移问题(不建议使用)
查看>>
jquery的colorbox关闭并传递数据到父窗
查看>>
使用Nginx、Keepalived构建文艺负载均衡
查看>>
phpmyadmin 开放远程登录的权限
查看>>
linux安装gcc和gcc-c++
查看>>
qq登陆错误提示
查看>>
bzoj 1192: [HNOI2006]鬼谷子的钱袋 思维 + 二进制
查看>>
没写完,没调完,咕咕咕的代码
查看>>
Android Studio使用技巧:导出jar包
查看>>
Problem E. TeaTree - HDU - 6430 (树的启发式合并)
查看>>
Kafka序列化和反序列化与示例
查看>>
【Windows 8 Store App】学习一:获取设备信息
查看>>
实现Windows程序的数据更新
查看>>
win10下VS2010中文输入法切换为英文卡死
查看>>
retinex相关代码汇总
查看>>
Cortex-M3 异常返回值EXC_RETURN
查看>>
Objective-C语言-内存管理
查看>>