有N个顾客,M个猪圈分别有 Ai 头,顾客依次打开一些猪圈 Oi ,购买一定数量 Ci 猪,开着的猪圈里的猪可以相互调动,下一个顾客来之前重新关上,问最终最多能卖出多少头猪。
有很明显的流动关系。
如果分阶段考虑猪圈,那么打开的猪圈间的调动关系即相互流动,每轮结束后,需要出售给顾客,即流向顾客。
那么构图显然,原点连向第一阶段各猪圈,容量为猪的初始头数,各阶段同猪圈间依次连边,打开的猪圈连向下阶段,以及当前阶段的顾客。顾客连向汇点,容量为最多购买头数。
另一种角度,由于猪圈的数量是不断变化的,因此可以分阶段考虑,最优方案下各阶段猪圈的数目是常量,令
xi,j
表示第
i
阶段第
由常量性质得,对每一个
xi,j=∑xi−1,k(j,k∈Oi)=∑xi+1,p+ci
由范围限制得:
x1,j=Aj;ci≤Ci
即流量平衡与流量限制。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ms(i) memset(i,0,sizeof i)
using namespace std;
const int inf = 0x3f3f3f3f, N = 10005, M = 600005;
int level[N], cnt, v[M], w[M], p[M], h[N], q[M], s, t;
void add(int a, int b, int c) {
p[++cnt] = h[a]; v[cnt] = b; w[cnt] = c; h[a] = cnt;
p[++cnt] = h[b]; v[cnt] = a; w[cnt] = 0; h[b] = cnt;
}
bool bfs() {
int f = 0, r = 0, u, i;
memset(level, -1, sizeof level);
q[r++] = s; level[s] = 1;
while (f < r) {
u = q[f++];
for (i = h[u]; i; i = p[i]) {
if (w[i] && level[v[i]] == -1) {
level[v[i]] = level[u] + 1;
q[r++] = v[i]; if (v[i] == t) return 1;
}
}
}
return false;
}
int dfs(int u, int low) {
int i, tmp = 0, res = 0;
if (u == t) return low;
for (i = h[u]; i && res < low; i = p[i]) {
if (w[i] && level[v[i]] == level[u] + 1) {
tmp = dfs(v[i], min(w[i], low - res));
w[i] -= tmp; w[i ^ 1] += tmp; res += tmp;
}
}
if (!res) level[u] = -1;
return res;
}
int dinic() {
int ans = 0;
while (bfs()) ans += dfs(s, inf);
return ans;
}
int a[N], pre[N];
int main() {
int i, j, k, n, m;
while (scanf("%d%d", &n, &m) == 2) {
s = 0; t = n + 1; cnt = 1;
ms(pre); ms(h);
for (i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (i = 1; i <= m; ++i) {
scanf("%d", &k);
while (k--) {
scanf("%d", &j);
if (!pre[j]) add(s, i, a[j]);
else add(pre[j], i, inf);
pre[j] = i;
}
scanf("%d", &k);
add(i, t, k);
}
printf("%d\n", dinic());
}
return 0;
}
PIGS
Description
Mirko works on a pig farm that consists of M locked pig-houses and Mirko can’t unlock any pighouse because he doesn’t have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of pigs.
All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
An unlimited number of pigs can be placed in every pig-house.
Write a program that will find the maximum number of pigs that he can sell on that day.
Input
The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N.
The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
A K1 K2 … KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, …, KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.
Output
The first and only line of the output should contain the number of sold pigs.
Sample Input
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
Sample Output
7