网络流代码合集

最大流

#include <bits/stdc++.h>
#define rei register int
#define maxn 100005
#define maxm 200005
using namespace std;
typedef long long ll;

struct edge {ll nxt, v, w;} e[maxm];

ll n, m, s, t, head[maxn], cnt = 1, dep[maxn], cur[maxn];

template <typename T> inline void read(T &x)
{
	x = 0; ll f = 1; char ch = getchar();
	while (!isdigit(ch)) {if (ch == '-') f = -f; ch = getchar();}
	while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
	x *= f;
}

inline void add_edge(ll u, ll v, ll w)
{
	e[++cnt].nxt = head[u];
	head[u] = cnt;
	e[cnt].v = v;
	e[cnt].w = w;
}

inline bool Bfs()
{
	queue<ll> Q;
	memset(dep, 0, sizeof(dep));
	dep[s] = 1;
	Q.push(s);
	while (Q.size())
	{
		ll u = Q.front(); Q.pop();
		cur[u] = head[u];
		for (rei i = head[u]; i; i = e[i].nxt)
		{
			ll v = e[i].v;
			if (!dep[v] && e[i].w)
			{
				dep[v] = dep[u] + 1;
				Q.push(v);
			}
		}
	}
	return dep[t] != 0; 
}

inline ll Dfs(ll u, ll flow)
{
	if (u == t) return flow;
	ll rest = flow;
	for (rei i = cur[u]; i; i = e[i].nxt)
	{
		ll v = e[i].v; cur[u] = i;
		if (dep[v] == dep[u] + 1 && e[i].w)
		{
			ll tmp = Dfs(v, min(e[i].w, rest));
			e[i].w -= tmp;
			e[i ^ 1].w += tmp;
			rest -= tmp;
			if (!rest) break;
		}
	}
	return flow - rest;
}

inline ll dinic()
{
	ll ans = 0;
	while (Bfs()) ans += Dfs(s, 1e18);
	return ans;
}

int main()
{
	read(n); read(m); read(s); read(t);
	for (rei i = 1; i <= m; i++)
	{
		ll u, v, w;
		read(u); read(v); read(w);
		add_edge(u, v, w); add_edge(v, u, 0);
	}
	printf("%lld", dinic());
	return 0;
}

费用流

在最大流的基础上增加了边权的限制,使用最短路处理,本质基于 Dinic

#include <bits/stdc++.h>
#define rei register int
#define N 100010
using namespace std;
typedef long long ll;
const int inf = 1e9;

template <typename T> inline void read(T &x)
{
	x = 0; T f = 1; char ch = getchar();
	while (!isdigit(ch)) {if (ch == '-') f = -f; ch = getchar();}
	while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
	x *= f;
}

int n, m, st, ed, head[N], edge_cnt = 1, incf[N], dis[N], pre[N], vis[N], maxflow, mincost;
struct edge {int nxt, v, w, c;} e[N << 1];

inline void add_edge(int u, int v, int w, int c) {e[++edge_cnt].nxt = head[u]; head[u] = edge_cnt; e[edge_cnt].v = v; e[edge_cnt].w = w; e[edge_cnt].c = c;}

inline bool SPFA()
{
	queue<int> q;
	memset(dis, 0x3f, sizeof(dis));
	memset(vis, 0, sizeof(vis));
	dis[st] = 0; q.push(st); vis[st] = 1; incf[st] = inf;
	while (!q.empty())
	{
		int u = q.front(); q.pop();
		vis[u] = 0;
		for (rei i = head[u]; i; i = e[i].nxt)
		{
			int v = e[i].v;
			if (dis[u] + e[i].c < dis[v] && e[i].w)
			{
				dis[v] = dis[u] + e[i].c;
				incf[v] = min(incf[u], e[i].w);
				pre[v] = i;
				if (!vis[v]) q.push(v), vis[v] = 1;
			}
		}
	}
	return dis[ed] != 1061109567;
}

inline void MCMF()
{
	while (SPFA())
	{
		int x = ed;
		maxflow += incf[ed];
		mincost += dis[ed] * incf[ed];
		int i;
		while (x != st)
		{
			i = pre[x];
			e[i].w -= incf[ed];
			e[i ^ 1].w += incf[ed];
			x = e[i ^ 1].v;
		}
	}
}

int main()
{
	read(n); read(m); read(st); read(ed);
	for (rei i = 1; i <= m; i++)
	{
		int u, v, c, w; read(u); read(v); read(w); read(c);
		add_edge(u, v, w, c); add_edge(v, u, 0, -c);
	}
	MCMF();
	printf("%d %d", maxflow, mincost);
	return 0;
}