HDU 4280 Island Transport(HLPP板子)题解
题意:
求最大流
思路:
\(1e5\)条边,偷了一个超长的\(HLPP\)板子。复杂度\(n^2 \sqrt{m}\)。但通常在随机情况下并没有isap快。
板子:
template<class T = int>
struct HLPP{
const int MAXN = 1e5 + 5;
const T INF = 0x3f3f3f3f;
struct edge{
int to, rev;
T f;
};
vector<edge> adj[maxn];
deque<int> lst[maxn];
vector<int> 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<int> 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<int> hlpp;
//hlpp.clear(n)
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <queue>
#define isdigit(a) (a>='0' && a<='9')
typedef long long LL;
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+5;
template<class T = int>
struct HLPP{
const int MAXN = 1e5 + 5;
const T INF = 0x3f3f3f3f;
struct edge{
int to, rev;
T f;
};
vector<edge> adj[maxn];
deque<int> lst[maxn];
vector<int> 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<int> 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<int> 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;
}
HDU 4280 Island Transport(HLPP板子)题解的更多相关文章
- HDU 4280 Island Transport(网络流,最大流)
HDU 4280 Island Transport(网络流,最大流) Description In the vast waters far far away, there are many islan ...
- HDU 4280 Island Transport
Island Transport Time Limit: 10000ms Memory Limit: 65536KB This problem will be judged on HDU. Origi ...
- Hdu 4280 Island Transport(最大流)
Island Transport Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- HDU 4280 Island Transport(无向图最大流)
HDU 4280:http://acm.hdu.edu.cn/showproblem.php?pid=4280 题意: 比较裸的最大流题目,就是这是个无向图,并且比较卡时间. 思路: 是这样的,由于是 ...
- HDU 4280 Island Transport(dinic+当前弧优化)
Island Transport Description In the vast waters far far away, there are many islands. People are liv ...
- HDU 4280 Island Transport(网络流)
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:pid=4280">http://acm.hdu.edu.cn/showproblem.php ...
- 【HDUOJ】4280 Island Transport
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4280 题意:有n个岛屿,m条无向路,每个路给出最大允许的客流量,求从最西的那个岛屿最多能运用多少乘客到 ...
- HDU 1385 Minimum Transport Cost 最短路径题解
本题就是使用Floyd算法求全部路径的最短路径,并且须要保存路径,并且更进一步须要依照字典顺序输出结果. 还是有一定难度的. Floyd有一种非常巧妙的记录数据的方法,大多都是使用这种方法记录数据的. ...
- HDU4280:Island Transport(最大流)
Island Transport Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
随机推荐
- Tensorflow-基础使用
Tensorflow基本概念 使用图(graphs)来表示计算任务 在被称之为会话(Session)的上下文(context)中执行图 使用tensor表示数据 通过变量(Variable)维护状态 ...
- Ansible自动化运维工具的使用
Ansible自动化运维工具的使用 host lnventory 管理主机 ip root账号密码 ssh端口 core mod ...
- vfd-cloud——一个适合练习上手的云存储网盘springboot项目(开发中)
vfd-cloud 一个基于SpringBoot的云存储网盘项目,适合练手学习SpringBoot,用到的技术栈列到了下面.支持用户的注册登陆及修改密码,利用邮箱进行验证.支持 ...
- WPF学习里程(二) XAML基础
1.什么是XAML? 官方语言: XAML是eXtensible Application Markup Language的英文缩写,相应的中文名称为可扩展应用程序标记语言,它是微软公司为构建应用程序用 ...
- LOJ10129
AHOI 2009 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为 nn 的数列,不妨设为 a1,a2,⋯,an.有如下三种操作形式: 把数列中的一段数全部乘一个值: 把 ...
- eclipse项目放到github
一,下载git ,配置用户名和邮箱: git config --global user.name "name" git config --global user.ema ...
- Java调用RestFul接口
使用Java调用RestFul接口,以POST请求为例,以下提供几种方法: 一.通过HttpURLConnection调用 1 public String postRequest(String url ...
- docker(mysql-redmine)
一.安装docker 首先查看自己的版本,我的是centos 版本为 [root@localhost redmine]# uname -r 3.10.0-862.el7.x86_64 移除旧版本 yu ...
- C++复习笔记(1)
复(su)习(cheng)一下c++. 1. 函数 函数重载:允许用同一函数名定义多个函数,但这些函数必须参数个数不同或类型不同. 函数模版: (应该是跟java的泛化类似,内容待扩展) templa ...
- hibernate学习笔记(1)结构与基本数据类型
一,概览 Hibernate负责从Java类到数据库表的映射,以及从Java数据类型到SQL数据类型的映射.另外还提供数据查询和检索功能.它可以显着减少在SQL和JDBC中手动处理数据的开发时间. ...