网络流模板-最大流
光速最大流:
namespace flow{ // }{{{
using typ = int;
constexpr int V = 1200, E = 120000;
int iv, is, it;
struct Edge{int to, nxt, lf;} es[E*2+2];
constexpr int EDGE_NIL = 0;
constexpr int INF = 0x3f3f3f3f;
int h[V]; typ ex[V];
int head[V], gap[V+1];
sd stack<int> hnods[V];
int maxh = 0, cnt = 2;
void init(int v, int s, int t){
iv=v, is=s, it=t;
memset(gap, 0, sizeof gap);
memset(head, 0, sizeof head);
memset(ex, 0, sizeof ex);
maxh = 0, cnt = 2;
}
void addflow(int s, int t, int c){
es[cnt] = {t, head[s], c}, head[s] = cnt++;
es[cnt] = {s, head[t], 0}, head[t] = cnt++;
}
void push(int x){
for(int i=head[x]; i!=EDGE_NIL; i=es[i].nxt){
if(x!=is && ex[x] == 0) break;
int t = es[i].to, w = es[i].lf;
if(!w || h[t] > h[x]) continue;
if(x==is || h[t] == h[x]-1){
int df = x==is ? w : (int)sd min(ex[x], (typ)w);
ex[x]-=df;
es[i].lf-=df, es[i^1].lf+=df;
if(ex[t] == 0 && t != it && t != is){
hnods[h[t]].push(t);
maxh = sd max(maxh, h[t]);
}
ex[t] += df;
}
}
}
void relabel(int x){
h[x] = iv;
for(int i=head[x]; i!=EDGE_NIL; i=es[i].nxt){
if(es[i].lf) h[x] = sd min(h[x], h[es[i].to]);
}
if(++h[x] < iv){
hnods[h[x]].push(x);
maxh = sd max(maxh, h[x]);
++gap[h[x]];
}
}
int gethiest(){
while(hnods[maxh].empty() && maxh >= 0) maxh--;
if(maxh == -1) return -1;
int ret = hnods[maxh].top();
hnods[maxh].pop();
return ret;
}
void bfs_init(){
memset(h, 0x3f, sizeof h);
h[it] = 0;
sd queue<int> todo;
todo.push(it);
while(!todo.empty()){
int s = todo.front();
todo.pop();
for(int i=head[s]; i!=EDGE_NIL; i=es[i].nxt){
int t=es[i].to;
if(es[i^1].lf && h[t]>h[s]+1){
h[t] = h[s]+1;
todo.push(t);
}
}
}
}
void hlpp(){
bfs_init();
if(h[is] == INF) return;
h[is] = iv;
UP(i, 0, iv) if(h[i]!=INF) gap[h[i]]++;
push(is);
int x;
while((x=gethiest())!=-1){
push(x);
if(ex[x]){
if(!--gap[h[x]]){
UP(i, 0, iv){
if(i==is || i==it) continue;
if(h[i]>h[x] && h[i]<iv+1) h[i] = iv+1;
}
}
relabel(x);
}
}
}
} // {}}}
龟速最大流:
namespace flow{ // }{{{
static constexpr int V = 1200, E = 120000;
static constexpr int EDGE_NIL = 0;
static constexpr int INF = 0x3f3f3f3f;
struct Edge{
int to, nxt, lf;
} es[E*2+2];
int h[V], head[V], ex[V], cnt, is, it, iv;
sd bitset<V> inque;
struct cmp{ bool operator()(int const &a, int const &b)const{return h[a] < h[b];} };
sd priority_queue<int, sd vector<int>, cmp> overflow;
void init(int v, int s, int t){
iv = v, is = s, it = t;
memset(head, 0, sizeof head);
memset(ex, 0, sizeof ex);
cnt = 2;
}
void addflow(int s, int t, int c){
es[cnt] = {t, head[s], c}, head[s] = cnt++;
es[cnt] = {s, head[t], 0}, head[t] = cnt++;
}
void push(int x){
for(int i=head[x]; i!=EDGE_NIL; i=es[i].nxt){
if(x!=is && ex[x] == 0) break;
int t = es[i].to, w = es[i].lf;
if(h[t] > h[x] || !w) continue;
if(x==is || h[t] == h[x]-1){
int df = x==is? w :sd min(ex[x], w);
ex[x] -= df;
ex[t] += df;
es[i].lf -= df;
es[i^1].lf += df;
if(!inque[t] && t!=is && t!=it) overflow.push(t), inque[t] = 1;
}
}
}
void relabel(int x){
h[x] = INF;
for(int i=head[x]; i!=EDGE_NIL; i=es[i].nxt){
int t = es[i].to, w = es[i].lf;
if(w) h[x] = sd min(h[x], h[t]+1);
}
}
void bfs(){
memset(h, 0x3f, sizeof h);
h[it] = 0;
sd queue<int> todo;
todo.push(it);
while(!todo.empty()){
int s = todo.front();
todo.pop();
inque[s] = false;
for(int i=head[s]; i!=EDGE_NIL; i=es[i].nxt){
int t=es[i].to, w = es[i^1].lf;
if(w && h[t]>h[s]+1){
h[t] = h[s]+1;
if(!inque[t]) todo.push(t), inque[t] = true;
}
}
}
}
void hlpp(){
bfs();
if(h[is] == INF) return;
h[is] = iv;
push(is);
while(!overflow.empty()){
int s = overflow.top();
overflow.pop();
inque[s] = false;
push(s);
while(ex[s]){
relabel(s);
push(s);
}
}
}
}; // {}}}