3280: 小R的烦恼
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 307 Solved: 157
[ Submit][ Status][ Discuss]
Description
小R最近遇上了大麻烦,他的程序设计挂科了。于是他只好找程设老师求情。善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题。
问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共持续n天,第i天需要a[i]个研究生来给他搬砖。研究生毕竟也是人,所以雇佣研究生是需要钱的,机智的程设老师已经联系好了m所大学,第j所大学共有l[j]个研究生,同时雇佣这所大学的一个研究生需要p[j]元钱。
本来程设老师满心欢喜的以为,这样捡最便宜的max{a[i]}个研究生雇来,就可以完成实验;结果没想到,由于他要求硕士生们每天工作25个小时不许吃饭睡觉上厕所喝水说话咳嗽打喷嚏呼吸空气,因此一天下来给他搬砖的所有研究生都会进入濒死状态。濒死状态的研究生,毫无疑问,就不能再进行工作了。但是机智的老师早早联系好了k家医院,第i家医院医治一个濒死的研究生需要d[i]天,并且需要q[i]元钱。
现在,程设老师想要知道,最少花多少钱,能够在这n天中满足每天的需要呢?若无法满足,则请输出”impossible”。注意,由于程设老师良心大大的坏,所以他是可以不把濒死的研究生送去医院的!
Input
本题包含多组数据;第一行是一个数T(T<=11),表示数据组数,以下T组数据。
对于每一组数据,第一行三个数,n,m,k;
以下一行n个数,表示a[1]…a[n]
接着一行2m个数,表示l[1],p[1]…l[n],p[n]
接着一行2k个数,表示d[1],q[1]…d[n],q[n]
Output
对于每组数据以样例的格式输出一行,两个数分别表示第几组数据和最少钱数。
Sample Input
2
3 2 1
10 20 30
40 90 15 100
1 5
3 2 1
10 20 30
40 90 15 100
2 5
3 2 1
10 20 30
40 90 15 100
1 5
3 2 1
10 20 30
40 90 15 100
2 5
Sample Output
Case 1: 4650
Case 2: impossible
Case 2: impossible
HINT
样例解释:买下90块钱的那40个研究生,另外再买10个100块钱的。这样,第一天用完的10个人全部送到医院,那么他们在第三天可以继续使用;同时,第二天和第三天都用新的研究生来弥补,这样一共需要花费40*90 + 10*100 + 5*10 = 4650元。
数据规模:
对于30%的数据中的每组数据,
满足n<=5,m,k<=2,其余数均小于等于100或者
n<=10,m,k<=10,其余数均小于等于20.
对于100%的数据
n,m,k<=50,其余数均小于等于100.
解题思路:与餐巾计划相同。简单建图
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define T 101
#define inf 0x7fffffff
using
namespace
std
;
inline
int
read
(
)
{
char
ch
=
getchar
(
)
;
int
f
=
1
,
x
=
0
;
while
(
!
(
ch
>=
'0'
&&
ch
<=
'9'
)
)
{
if
(
ch
==
'-'
)
f
=
-
1
;
ch
=
getchar
(
)
;
}
while
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
x
=
x
*
10
+
(
ch
-
'0'
)
;
ch
=
getchar
(
)
;
}
return
x
*
f
;
}
int
n
,
m
,
k
,
cnt
,
ans
;
int
a
[
105
]
,
q
[
105
]
,
h
[
105
]
,
head
[
105
]
,
d
[
105
]
,
from
[
105
]
;
bool
inq
[
105
]
;
struct
edge
{
int
from
,
to
,
next
,
c
,
v
;
}
e
[
100001
]
;
void
ins
(
int
u
,
int
v
,
int
w
,
int
c
)
{
e
[
++
cnt
]
.
from
=
u
;
e
[
cnt
]
.
to
=
v
;
e
[
cnt
]
.
next
=
head
[
u
]
;
head
[
u
]
=
cnt
;
e
[
cnt
]
.
c
=
c
;
e
[
cnt
]
.
v
=
w
;
}
void
insert
(
int
u
,
int
v
,
int
w
,
int
c
)
{
ins
(
u
,
v
,
w
,
c
)
;
ins
(
v
,
u
,
0
,
-
c
)
;
}
bool
spfa
(
)
{
for
(
int
i
=
0
;
i
<=
T
;
i
++
)
d
[
i
]
=
inf
;
int
t
=
0
,
w
=
1
;
d
[
0
]
=
0
;
inq
[
0
]
=
1
;
q
[
0
]
=
0
;
while
(
t
!=
w
)
{
int
now
=
q
[
t
]
;
t
++
;
if
(
t
==
T
)
t
=
0
;
for
(
int
i
=
head
[
now
]
;
i
;
i
=
e
[
i
]
.
next
)
if
(
e
[
i
]
.
v
&&
d
[
e
[
i
]
.
to
]
>
d
[
now
]
+
e
[
i
]
.
c
)
{
d
[
e
[
i
]
.
to
]
=
d
[
now
]
+
e
[
i
]
.
c
;
from
[
e
[
i
]
.
to
]
=
i
;
if
(
!
inq
[
e
[
i
]
.
to
]
)
{
inq
[
e
[
i
]
.
to
]
=
1
;
q
[
w
++
]
=
e
[
i
]
.
to
;
if
(
w
==
T
)
w
=
0
;
}
}
inq
[
now
]
=
0
;
}
if
(
d
[
T
]
==
inf
)
return
0
;
return
1
;
}
void
mcf
(
)
{
int
x
=
inf
;
for
(
int
i
=
from
[
T
]
;
i
;
i
=
from
[
e
[
i
]
.
from
]
)
x
=
min
(
x
,
e
[
i
]
.
v
)
;
for
(
int
i
=
from
[
T
]
;
i
;
i
=
from
[
e
[
i
]
.
from
]
)
{
e
[
i
]
.
v
-=
x
;
e
[
i
^
1
]
.
v
+=
x
;
ans
+=
e
[
i
]
.
c
*
x
;
}
}
int
main
(
)
{
int
x
,
y
,
test
=
read
(
)
;
for
(
int
l
=
1
;
l
<=
test
;
l
++
)
{
printf
(
"Case %d: "
,
l
)
;
cnt
=
1
;
ans
=
0
;
memset
(
head
,
0
,
sizeof
(
head
)
)
;
n
=
read
(
)
;
m
=
read
(
)
;
k
=
read
(
)
;
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
{
a
[
i
]
=
read
(
)
;
insert
(
i
,
T
,
a
[
i
]
,
0
)
;
insert
(
0
,
i
+
n
,
a
[
i
]
,
0
)
;
if
(
i
<
n
)
insert
(
i
,
i
+
1
,
inf
,
0
)
;
}
for
(
int
i
=
1
;
i
<=
m
;
i
++
)
{
x
=
read
(
)
;
y
=
read
(
)
;
insert
(
0
,
1
,
x
,
y
)
;
}
for
(
int
i
=
1
;
i
<=
k
;
i
++
)
{
x
=
read
(
)
;
y
=
read
(
)
;
for
(
int
j
=
1
;
j
<=
n
;
j
++
)
if
(
j
+
x
+
1
<=
n
)
insert
(
n
+
j
,
j
+
x
+
1
,
inf
,
y
)
;
}
while
(
spfa
(
)
)
mcf
(
)
;
bool
f
=
0
;
for
(
int
i
=
2
;
i
<=
cnt
;
i
+=
2
)
if
(
e
[
i
]
.
to
==
T
&&
e
[
i
]
.
v
)
{
printf
(
"impossible\n"
)
;
f
=
1
;
break
;
}
if
(
!
f
)
printf
(
"%d\n"
,
ans
)
;
}
return
0
;
}