Luo Gu · [24 network flow problem] load balancing

~ Ann has shown signs of more than write a few today. Here is the Portal: Luo Gu P4016 load balancing

24 network flow problems So there are so water problem ah. It would have been too lazy to write 24 questions ...... neat solution to a problem or write it .

Each repository has initial stock, S corresponds to each warehouse even from an initial value of the capacity side. Then the total inventory divided equally to these warehouses, so from each warehouse to the capacity of even a T side of the mean. Because the allocation of capacity is determined, so we wrote a fee stream, the problem is that the minimum cost flow . Front cost to the S and T are 0, then consider transportation. Transport, then left the ring can also be transported right transport, [I'm not sure but the feeling will pan In order to avoid the pan, we put every dot split into two, one for the initial stock issued by the S, a responsible receiving a transport company to a T. Initial stock from a reception point to an adjacent warehouse costs even side 1, and then run the minimum cost flow. Gone.

Because the total inflow equal to the confluence, so the problem will not think of a flow losses.

The code -

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 300
#define maxm 20000
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

struct edge {int to, w, f, nxt;} e[maxm];
int head[maxn], k = 0;
void add(int u, int v, int w, int f) {
	e[k] = {v, w, f, head[u]}; head[u] = k++;
	e[k] = {u, 0, -f, head[v]}; head[v] = k++;
}

int S, T, dis[maxn], pre[maxn], incf[maxn];
bool vis[maxn];
bool spfa() {
	memset(dis, 0x3f, sizeof dis); dis[S] = 0;
	memset(vis, 0, sizeof vis); vis[S] = true;
	queue<int> q; incf[S] = INF; q.push(S);
	while(q.size()) {
		register int u = q.front(), v; q.pop(); vis[u] = false;
		for(int i = head[u]; ~i; i = e[i].nxt) {
			v = e[i].to; if(e[i].w && dis[u] + e[i].f < dis[v]) {
				dis[v] = dis[u] + e[i].f;
				incf[v] = min(incf[u], e[i].w); pre[v] = i;
				if(!vis[v]) q.push(v), vis[v] = true;
			}
		}
	}
	if(dis[T] == INF) return false; return true;
}

ll ans = 0;
void update() {
	register int u = T, i;
	while(u != S) {
		i = pre[u];
		e[i].w -= incf[T], e[i ^ 1].w += incf[T];
		u = e[i ^ 1].to;
	}
	ans += 1ll * incf[T] * dis[T];
}

int n, a[maxn];
signed main() {
	memset(head, -1, sizeof head);
	n = read(); S = 0, T = n * 2 + 1;
	register int sum = 0;
	for(int i = 1; i <= n; i++) a[i] = read(), sum += a[i];
	
	sum = sum / n;//现在sum就是均值了
	for(int i = 1, x; i <= n; i++) {//如上文解释连边
		x = a[i]; add(S, i, x, 0), add(i + n, T, sum, 0);
		add(i, i + n, INF, 0);
		if(i == 1) add(i + n, n, INF, 1);//环形边界
		else add(i + n, i - 1, INF, 1);
		if(i == n) add(i + n, 1, INF, 1);
		else add(i + n, i + 1, INF, 1);
	}
	
	while(spfa()) update();
	printf("%lld\n", ans);
	return 0;
}

Meet the assessment
:) --End--

Published 158 original articles · won praise 23 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_43326267/article/details/104189159