BZOJ_3280_小R的烦恼_最小费用最大流
2018-06-03 09:17
267 查看
BZOJ_3280_小R的烦恼_最小费用最大流
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接着一行2m个数,表示l[1],p[1]…l
,p
接着一行2k个数,表示d[1],q[1]…d
,q
n,m,k<=50,其余数均小于等于100.
Output
对于每组数据以样例的格式输出一行,两个数分别表示第几组数据和最少钱数。
Sample Input
23 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: 4650Case 2: impossible
样例解释:
买下90块钱的那40个研究生,另外再买10个100块钱的。这样,第一天用完的10个人全部送到医院,那么他们在第
三天可以继续使用;同时,第二天和第三天都用新的研究生来弥补,这样一共需要花费40*90 + 10*100 + 5*10 =
4650元。 类似餐巾计划问题,将人拆成两个点(i,i')分别表示活的和死的。 对学校有S->1(l[j],p[j])。对于第i天剩下的:S->i'(a[i],0)。 i->i+1(inf,0) i'-i'+1(inf,0) 医院:i'->i+d[i](inf,q[i]) 流出去:i->T(a[i],0)。 代码:
#include <cstdio> #include <string.h> #include <algorithm> using namespace std; #define N 1050 #define M 1000050 #define S (n+n+1) #define T (n+n+2) #define inf 1<<30 int head ,to[M],nxt[M],val[M],flow[M],cnt,n,m,K,a_ ,l_ ,p_ ,d_ ,q_ ; int Q ,l,r,dis ,inq ,path ,sum,TTT; inline void add(int u,int v,int f,int c) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=c; to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-c; } bool spfa() { memset(dis,0x3f,sizeof(dis)); memset(path,0,sizeof(path)); l=r=0; Q[r++]=S; dis[S]=0; inq[S]=1; while(l!=r) { int x=Q[l++],i;inq[x]=0; if(l==T) l=0; for(i=head[x];i;i=nxt[i]) { if(dis[to[i]]>dis[x]+val[i]&&flow[i]) { dis[to[i]]=dis[x]+val[i]; path[to[i]]=i^1; if(!inq[to[i]]) { inq[to[i]]=1; Q[r++]=to[i]; if(r==T) r=0; } } } } return path[T]; } void mcmf() { TTT++; int maxf=0,minc=0; while(spfa()) { int i,nf=1<<30; for(i=T;i!=S;i=to[path[i]]) { nf=min(nf,flow[path[i]^1]); } maxf+=nf; for(i=T;i!=S;i=to[path[i]]) { minc+=nf*val[path[i]^1]; flow[path[i]]+=nf; flow[path[i]^1]-=nf; } } // printf("%d %d %d\n",maxf,minc,sum); if(maxf<sum) { printf("Case %d: impossible\n",TTT); }else { printf("Case %d: %d\n",TTT,minc); } } void solve() { memset(head,0,sizeof(head)); cnt=1; sum=0; int i,j; scanf("%d%d%d",&n,&m,&K); for(i=1;i<=n;i++) scanf("%d",&a_[i]),add(i,T,a_[i],0),sum+=a_[i],add(S,i+n,a_[i],0); for(i=1;i<=m;i++) scanf("%d%d",&l_[i],&p_[i]),add(S,1,l_[i],p_[i]); for(i=1;i<=K;i++) scanf("%d%d",&d_[i],&q_[i]); for(i=1;i<=n;i++) { if(i!=n) add(i,i+1,inf,0),add(i+n,i+n+1,inf,0); for(j=1;j<=K;j++) { if(i+d_[j]+1<=n) add(i+n,i+d_[j]+1,inf,q_[j]); } } mcmf(); } int main() { int cs; scanf("%d",&cs); while(cs--) { solve(); } }
相关文章推荐
- 【BZOJ3280】小R的烦恼 最小费用最大流
- 【bzoj3280】小R的烦恼 费用流
- bzoj3280 小R的烦恼
- 小R的烦恼 BZOJ3280
- 【bzoj3280】小R的烦恼
- Bzoj3280 小R的烦恼
- [BZOJ3280]小R的烦恼(费用流)
- 【BZOJ】【3280】小R的烦恼
- 【费用流】bzoj3280 小R的烦恼
- BZOJ网络流+费用流大合集:【3280小R的烦恼】
- bzoj1221 [HNOI2001]软件开发 & bzoj3280 小R的烦恼
- bzoj3280 小R的烦恼
- bzoj1221 [HNOI2001]软件开发 & bzoj3280 小R的烦恼
- BZOJ3280: 小R的烦恼
- bzoj 3280: 小R的烦恼 (网络流)
- BZOJ 3280: 小R的烦恼 & BZOJ 1221: [HNOI2001] 软件开发
- BZOJ 3280: 小R的烦恼 费用流 多路增广
- BZOJ3280: 小R的烦恼
- bzoj3280: 小R的烦恼
- bzoj 3280: 小R的烦恼 费用流