[洛谷P4722]【模板】最大流 加强版 / 预流推进

会$TLE$。。。

C++ Code:(HLPP)

#pragma GCC optimize(3)
#pragma GCC optimize("unroll-loops")
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define maxn 1210
#define maxm 120010
const int inf = 0x3f3f3f3f;
inline int min(int a, int b) {return a < b ? a : b;}
namespace Network_Flow {
	int st, ed, MF, n;
	int head[maxn], cnt = 2;
	struct Edge {
		int to, nxt, w;
	} e[maxm << 1];
	inline void addE(int a, int b, int c) {
		e[cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
		e[cnt ^ 1] = (Edge) {a, head[b], 0}; head[b] = cnt ^ 1;
		cnt += 2;
	}
	bool inq[maxn];
	int GAP[maxn << 1], h[maxn];
	int prs[maxn];
	struct cmp {
		inline bool operator () (int a, int b) const {return h[a] < h[b];}
	};
	std::priority_queue<int, std::vector<int>, cmp> q;
	inline bool N(int p) {return p != st && p != ed;}
	inline void Push(int u) {
		const int H = h[u] - 1;
		for (register int i = head[u]; i; i = e[i].nxt) {
			int v = e[i].to;
			if (e[i].w && h[v] == H) {
				int w = min(prs[u], e[i].w);
				e[i].w -= w, e[i ^ 1].w += w;
				prs[u] -= w, prs[v] += w;
				if (v != st && v != ed && !inq[v]) {
					q.push(v);
					inq[v] = true;
				}
				if (!prs[u]) return ;
			}
		}
	}
	inline void Gap(int H) {
		for (register int i = 1; i <= n; i++) if (N(i) && H < h[i] && h[i] <= n) h[i] = n + 1;
	}
	namespace BFS {
		int Q[maxn], H, T;
		inline bool bfs() {
			memset(h, 0x3f, sizeof h);
			h[Q[H = T = 0] = ed] = 1;
			while (H <= T) {
				int u = Q[H++];
				for (int i = head[u]; i; i = e[i].nxt) {
					int v = e[i].to;
					if (e[i ^ 1].w && h[v] > h[u] + 1) {
						h[v] = h[u] + 1;
						Q[++T] = v;
					}
				}
			}
			return h[ed] != inf;
		}
	}
	inline void relabel(int u) {
		int &H = h[u] = inf;
		for (register int i = head[u]; i; i = e[i].nxt) {
			int v = e[i].to;
			if (e[i].w && h[v] + 1 < H) H = h[v] + 1;
		}
	}
	inline void HLPP(int __S, int __T) {
		st = __S, ed = __T;
		if (!BFS::bfs()) return ;
		h[st] = n;
		for (register int i = 1; i <= n; i++) if (h[i] < inf) GAP[h[i]]++;
		for (register int i = head[st]; i; i = e[i].nxt) {
			int v = e[i].to, &w = e[i].w;
			if (!w) continue;
			e[i ^ 1].w += w, prs[st] -= w, prs[v] += w;
			w = 0;
			if (v != ed && !inq[v]) {
				q.push(v);
				inq[v] = true;
			}
		}
		while (!q.empty()) {
			int u = q.top(); q.pop();
			inq[u] = false; Push(u);
			if (!prs[u]) continue;
			if (!--GAP[h[u]]) for (register int i = 1; i <= n; i++) if (i != st && i != ed && h[u] < h[i] && h[i] <= n) h[i] = n + 1; //Gap(h[u]);
			relabel(u); GAP[h[u]]++;
			q.push(u); inq[u] = true;
		}
		MF = prs[ed];
	}
	inline void clear() {
		memset(head, 0, sizeof head); cnt = 2;
		memset(GAP, 0, sizeof GAP); memset(prs, 0, sizeof prs);
		while (!q.empty()) q.pop();
		MF = 0;
	}
}
#define read() R::READ()
#include <cctype>
namespace R {
	int x;
	#ifdef ONLINE_JUGER
	#define M 1 << 25
	char op[M], *ch;
	inline void init() {fread(ch = op, 1, M, stdin);}
	inline int READ() {
		while (isspace(*ch)) ch++;
		for (x = *ch & 15, ch++; isdigit(*ch); ch++) x = x * 10 + (*ch & 15);
		return x;
	}
	#undef M
	#else
	char ch;
	inline int READ() {
		ch = getchar();
		while (isspace(ch)) ch = getchar();
		for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
		return x;
	}
	#endif
}
int n, m, st, ed;
int main() {
	#ifdef ONLINE_JUGER
	R::init();
	#endif
	Network_Flow::n = read(), m = read(), st = read(), ed = read();
	for (register int i = 0, a, b, c; i < m; i++) {
		a = read(), b = read(), c = read();
		Network_Flow::addE(a, b, c);
	}
	Network_Flow::HLPP(st, ed);
	printf("%d\n", Network_Flow::MF);
	return 0;
}

 

posted @ 2018-10-16 18:54  Memory_of_winter  阅读(216)  评论(0编辑  收藏  举报