Loading

「学习笔记」费用流

费用流,和最大流的区别就是它的边权多了费用这个权值,一般是最小费用最大流,即在保证最大流的前提下做到费用最小
做法:贪心思想,按照费用来找出最短路,在所有的最短路上找增广路,直到没有增广路为止

ll spfa() {
	for (int i = S; i <= T; ++ i) {
		dis[i] = 1e18;
		cur[i] = h[i];
	}
	deque<int> q;
	q.push_back(S);
	vis[S] = 1, dis[S] = 0;
	while (!q.empty()) {
		int u = q.front();
		q.pop_front();
		vis[u] = 0;
		for (int i = h[u]; i; i = e[i].nxt) {
			int v = e[i].v;
			if (dis[v] > dis[u] + e[i].f && e[i].w) {
				dis[v] = dis[u] + e[i].f;
				if (!vis[v]) {
					vis[v] = 1;
					if (!q.empty() && dis[v] <= dis[q.front()]) {
						q.push_front(v);
					}
					else {
						q.push_back(v);
					}
				}
			}
		}
	}
	return dis[T] < 1e18;
}

ll dfs(int u, ll flow) {
	if (u == T) {
		return flow;
	}
	vis[u] = 1;
	ll rest = flow, rlow = 0;
	for (int &i = cur[u]; i && rest; i = e[i].nxt) {
		int v = e[i].v;
		if (dis[v] == dis[u] + e[i].f && !vis[v] && e[i].w) {
			if ((rlow = dfs(v, min(rest, e[i].w)))) {
				e[i].w -= rlow;
				e[i ^ 1].w += rlow;
				rest -= rlow;
				cost += rlow * e[i].f;
			}
		}
	}
	vis[u] = 0;
	return flow - rest;
}
	while (spfa()) {
		while (dfs(S, 1e18));
	}
posted @ 2023-01-16 11:33  yi_fan0305  阅读(36)  评论(0编辑  收藏  举报