网络流EK算法模板

\(EK\)算法的思想就是每一次找一条增广路进行增广。

注意几个点:

  • 存图时\(head\)数组要设为\(-1\)
  • 存图的代码是这样的:
inline void add(int u, int v, int w)
{
	ver[tot] = v, fro[tot] = u, edge[tot] = w, nxt[tot] = head[u], head[u] = tot++;
	ver[tot] = u, fro[tot] = v, edge[tot] = 0, nxt[tot] = head[v], head[v] = tot++;//注意最后才tot++,且需要建流量为0的反边
}

具体实现参考代码:

#include <bits/stdc++.h>
#define itn int
#define gI gi

using namespace std;

inline int gi()
{
	int f = 1, x = 0; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar();
	return f * x;
}

const int maxn = 100003;

int n, m, s, t, tot, fro[maxn * 2], head[maxn], ver[maxn * 2], nxt[maxn * 2], edge[maxn * 2];
int flow[maxn], pre[maxn], pos[maxn], ans;

inline void add(int u, int v, int w)
{
	ver[tot] = v, fro[tot] = u, edge[tot] = w, nxt[tot] = head[u], head[u] = tot++;
	ver[tot] = u, fro[tot] = v, edge[tot] = 0, nxt[tot] = head[v], head[v] = tot++;
}

queue <int> q;

inline int Max_flow(int s, int t)
{
	memset(pos, -1, sizeof(pos));
	memset(pre, -1, sizeof(pre));
	while (!q.empty()) q.pop();
	q.push(s);
	flow[s] = 0x3f3f3f3f;
	//以上为初始化
	while (!q.empty())
	{
		int u = q.front(); q.pop();
		if (u == t) return flow[u];//找到了一条增广路
		for (int i = head[u]; i != -1; i = nxt[i])//遍历出边
		{
			int v = ver[i], w = edge[i];
			if (pre[v] == -1 && w > 0)//下一个点还可以增广
			{
				pre[v] = u;//记录前驱
				pos[v] = i;//记录当前边的编号
				flow[v] = min(flow[u], w);//记录流量
				q.push(v);//放入队列
			}
		}
	}
	return -1;
}

inline void EK(int s, int t)
{
	int ins = 0;
	while ((ins = Max_flow(s, t)) != -1)//当前还存在增广路
	{
		int k = t;//向前推进
		while (k != s)
		{
			edge[pos[k]] -= ins;//边的流量减去当前增广出的最大流量
			edge[pos[k] ^ 1] += ins;//反边则加上最大流量
			k = pre[k];//向前记录
		}
		ans += ins;//增加答案
	}
}

int main()
{
	n = gi(), m = gi(), s = gi(), t = gi();
	memset(head, -1, sizeof(head));//记得初始值设为-1
	for (int i = 1; i <= m; i+=1)
	{
		int u = gi(), v = gi(), w = gi();
		add(u, v, w);//建边
	}
	EK(s, t);//EK算法跑网络流
	printf("%d\n", ans);//输出答案
	return 0;
}
posted @ 2019-11-08 21:51  csxsi  阅读(292)  评论(0编辑  收藏  举报