网络流(零)——准备工作

最大流dinic:

int dep[N], Q[N];
inline bool bfs() {
	memset(dep, 0, sizeof(dep)); dep[st] = 1;
	int l = 0, r = 1; Q[1] = st;
	while(l < r) {
		int u = Q[++l];
		for(int i = head[u], v; i; i = e[i].next) {
			if(!dep[v = e[i].to] && e[i].z) {
				Q[++r] = v;
				dep[v] = dep[u] + 1;
			}
		}
	}
	return dep[ed];
}
int cur[N];
int dfs(int u, int s1) {
	if(u == ed || !in) return in;
	int s2 = s1;
	for(int &i = cur[u]; i; i = e[i].next) {
		int v = e[i].to;
		if(dep[v] == dep[u] + 1 && e[i].z) {
			int x = dfs(v, min(s1, e[i].z));
			if(!x) dep[v] = 0;
			s1-= x; e[i].z-= x; e[i^1].z+= x;
			if(!s1) return s2;
		}
	}
	return s2 - s1;
}
inline int dinic() {
	int ret = 0;
	while(bfs()) {
		memcpy(cur, head, sizeof(cur));
		ret+= dfs(st, inf);
	}
	return ret;
}

EK费用流:

int d[N], incf[N], pre[N], vis[N];
inline bool spfa() {
	queue<int> Q;
	memset(d, 0xcf, sizeof(d));
	memset(vis, 0, sizeof(vis));
	Q.push(st); d[st] = 0; vis[st] = 1;
	incf[st] = 1<<30;
	while(Q.size()) {
		int x = Q.front(); Q.pop(); vis[x] = 0;
		for(int i = head[x]; i; i = e[i].next) {
			if(!e[i].c) continue;
			int y = e[i].to;
			if(d[y] < d[x] + e[i].cost) {
				d[y] = d[x] + e[i].cost;
				incf[y] = min(incf[x], e[i].c);
				pre[y] = i;
				if(!vis[y]) vis[y] = 1, Q.push(y);
			}
		}
	}
	if(d[ed] == 0xcfcfcfcf) return false;
	return true;
}
int ans = 0, maxflow = 0;
inline void update() {
	int x = ed;
	while(x != st) {
		int i = pre[x];
		e[i].c-= incf[ed];
		e[i^1].c+= incf[ed];
		x = e[i^1].to;
	}
	maxflow+= incf[ed];
	ans+= d[ed] * incf[ed];
}
inline void EK_cost() {while(spfa()) update();}

猜你喜欢

转载自blog.csdn.net/richard_for_oi/article/details/79821722