一、题目描述
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 arives, 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
二、分析
这道题的见图有些复杂,不过看到猪圈有1000个,而顾客有100个,可以发现不可能以猪圈为顶点。新设两个顶点,一个s,一个t,当第一个顾客有个一个猪圈的钥匙时,就有一条从s到该顾客的边,容量为猪圈中猪的数量,以后另外有顾客有这个猪圈的钥匙是,则有一条从前一个顾客到这个顾客的边,容量为无穷大,同时每个顾客都有到t的边,容量为顾客的需求量。求最大流,使用Relabel-To-Front算法,具体算法:最大流问题
三、代码
1
#include<iostream>
2
#include<list>
3
using namespace std;
4
#define MAXM 1001
5
#define MAXN 101
6
int s, t;
7
int n, m;
8
int pig[MAXM], record[MAXM];
9
int c[MAXN+2][MAXN+2];
10
int f[MAXN+2][MAXN+2];
11
int e[MAXN+2];
12
int h[MAXN+2];
13
list<int> l;
14
list<int>::iterator lit;
15
list<int> neb[MAXN+2];
16
list<int>::iterator nit[MAXN+2];
17
void push(int u, int v)
18

{
19
int d = min(e[u], c[u][v] - f[u][v]);
20
f[u][v] += d;
21
f[v][u] = -f[u][v];
22
e[u] -= d;
23
e[v] += d;
24
}
25
void relabel(int u)
26

{
27
int mh = INT_MAX;
28
for(int i=0; i<n+2; i++)
29
{
30
if(c[u][i] > f[u][i])
31
mh = min(mh, h[i]);
32
}
33
h[u] = mh + 1;
34
}
35
void discharge(int u)
36

{
37
while(e[u] > 0)
38
{
39
if(nit[u] == neb[u].end())
40
{
41
relabel(u);
42
nit[u] = neb[u].begin();
43
continue;
44
}
45
int v = *nit[u];
46
if(c[u][v] > f[u][v] && h[u] == h[v]+1)
47
push(u, v);
48
else
49
nit[u]++;
50
}
51
}
52
void init_preflow()
53

{
54
memset(h, 0, sizeof(h));
55
memset(e, 0, sizeof(e));
56
h[s] = n+2;
57
for(int i=0; i<n+2; i++)
58
{
59
if(c[s][i] == 0)
60
continue;
61
f[s][i] = c[s][i];
62
f[i][s] = -f[s][i];
63
e[i] = c[s][i];
64
e[s] -= c[s][i];
65
}
66
}
67
void relabel_to_front()
68

{
69
init_preflow();
70
for(int i=1; i<=n; i++)
71
{
72
l.push_back(i);
73
nit[i] = neb[i].begin();
74
}
75
lit = l.begin();
76
while(lit != l.end())
77
{
78
int u = *lit;
79
int old = h[u];
80
discharge(u);
81
if(h[u] > old)
82
{
83
l.erase(lit);
84
l.push_front(u);
85
lit = l.begin();
86
}
87
lit++;
88
}
89
}
90
int main()
91

{
92
memset(c, 0, sizeof(c));
93
memset(f, 0, sizeof(f));
94
memset(record, -1, sizeof(record));
95
scanf("%d%d", &m, &n);
96
s = 0; t = n+1;
97
for(int i=1; i<=m; i++)
98
scanf("%d", &pig[i]);
99
for(int i=1; i<=n; i++)
100
{
101
int a, k, b;
102
scanf("%d", &a);
103
for(int j=0; j<a; j++)
104
{
105
scanf("%d", &k);
106
if(record[k] == -1)
107
{
108
if(c[s][i] == 0)
109
{
110
c[s][i] = pig[k];
111
neb[s].push_back(i);
112
neb[i].push_back(s);
113
}
114
else
115
c[s][i] += pig[k];
116
record[k] = i;
117
}
118
else
119
{
120
c[record[k]][i] = INT_MAX;
121
neb[record[k]].push_back(i);
122
neb[i].push_back(record[k]);
123
}
124
}
125
scanf("%d", &b);
126
c[i][t] = b;
127
neb[i].push_back(t);
128
neb[t].push_back(i);
129
}
130
relabel_to_front();
131
printf("%d\n", e[t]);
132
}
posted on 2009-06-26 16:15
Icyflame 阅读(1324)
评论(0) 编辑 收藏 引用 所属分类:
解题报告