[洛谷P4174][NOI2006]最大获利

题目大意:Petya and Graph,数据范围改成$n\leqslant5\times10^3,m\leqslant5\times10^4$

题解:同上

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#define maxn 5010
#define maxm 50010
const int N = maxn + maxm, M = N + 2 * maxm;
const int inf = 0x3f3f3f3f;

namespace Network_Flow {
	int lst[N], head[N], cnt = 1;
	struct Edge {
		int to, nxt, w;
	} e[M << 1];
	inline void addedge(int a, int b, int c) {
		e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
		e[++cnt] = (Edge) { a, head[b], 0 }; head[b] = cnt;
	}

	int n, st, ed, MF;
	int GAP[N], d[N];
	int q[N], h, t;

	void init() {
		GAP[d[ed] = 1] = 1;
		for (int i = 0; i < n; ++i) lst[i] = head[i];
		q[h = t = 0] = ed;
		while (h <= t) {
			int u = q[h++];
			for (int i = head[u]; i; i = e[i].nxt) {
				int v = e[i].to;
				if (!d[v]) {
					d[v] = d[u] + 1;
					++GAP[d[v]];
					q[++t] = v;
				}
			}
		}
	}
	int dfs(int u, int low) {
		if (!low || u == ed) return low;
		int w, res = 0;
		for (int &i = lst[u]; i; i = e[i].nxt) if (e[i].w) {
			int v = e[i].to;
			if (d[u] == d[v] + 1) {
				w = dfs(v, std::min(low, e[i].w));
				res += w, low -= w;
				e[i].w -= w, e[i ^ 1].w += w;
				if (!low) return res;
			}
		}
		if (!(--GAP[d[u]])) d[st] = n + 1;
		++GAP[++d[u]], lst[u] = head[u];
		return res;
	}
	void ISAP(int S, int T) {
		st = S, ed = T;
		init();
		while (d[st] <= n) MF += dfs(st, inf);
	}
}
using Network_Flow::addedge;

int n, m, sum;
int main() {
	scanf("%d%d", &n, &m); Network_Flow::n = n + m + 2;
	int st = 0, ed = n + m + 1;
	for (int i = 1, x; i <= n; ++i) {
		scanf("%d", &x);
		addedge(st, i, x);
	}
	for (int i = 1, a, b, c; i <= m; ++i) {
		scanf("%d%d%d", &a, &b, &c);
		addedge(a, n + i, inf);
		addedge(b, n + i, inf);
		addedge(n + i, ed, c);
		sum += c;
	}
	Network_Flow::ISAP(st, ed);
	printf("%d\n", sum - Network_Flow::MF);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/10341441.html
今日推荐