网络流模板-最大流

光速最大流:

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);
		}
	}
}
}; // {}}}
posted @ 2023-05-23 10:42  383494  阅读(3)  评论(0编辑  收藏  举报