【模板】网络最大流

题意简述

给出一个网络图,以及其源点和汇点,求出其网络最大流。

代码

#include <queue> 
#include <cstdio>
#include <cstring>
#include <algorithm>
int n, m, s, t, cnt = 1, u, v, w, ans;
int h[10010], nxt[200010], va[200010], to[200010], dep[10010], lst[10010];
inline void add_edge(const int& u, const int& v, const int& w)
{
	to[++cnt] = v;
	va[cnt] = w;
	nxt[cnt] = h[u];
	h[u] = cnt;
}
bool bfs()
{
	std::queue <int> q;
	memset(dep, 0, sizeof(dep));
	q.push(t);
	dep[t] = 1;
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (register int i = h[u]; i; i = nxt[i])
			if (va[i ^ 1] && !dep[to[i]])
			{
				dep[to[i]] = dep[u] + 1;
				if (to[i] == s) return 1;
				q.push(to[i]);
			}
	}
	return 0;
}
int dfs(const int& u, int flow)
{
	int ss = 0;
	if (u == t) return flow;
	for (int& i = lst[u]; i; i = nxt[i])
		if (dep[to[i]] == dep[u] - 1 && va[i])
		{
			int tmp = dfs(to[i], std::min(flow, va[i]));
			va[i] -= tmp;
			va[i ^ 1] += tmp;
			flow -= tmp;
			ss += tmp;
			if (!flow) return ss;
		}
	if (!ss) dep[u] = 0;
	return ss;
}
int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	for (register int i = 1; i <= m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		add_edge(u, v, w);
		add_edge(v, u, 0);
	}
	while (bfs())
	{
		for (register int i = 1; i <= n; ++i) lst[i] = h[i];
		ans += dfs(s, 0x7fffffff);
	}
	printf("%d
", ans);
}
原文地址:https://www.cnblogs.com/xuyixuan/p/11191008.html