码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3280: 小R的烦恼

时间:2016-01-23 01:31:04      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

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

Sample Output

Case 1: 4650
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.

 
题解:
先要将每一天拆成两个点分别表示这天开始和结束
由S向第一天的开始练m条边,容量和费用分别为每个学校的学生个数和单价,表示要买多少学生和所需的费用
由每天开始向T连容量为每天所需的学生个数,费用为0,表示这天要用这么多的学生
由每天开始向下一天开始连容量为inf,费用为0的边,表示这天没有用到的学生可以留到下一天用
由S向每天的结束连容量为每天所需的学生个数,费用为0,表示这天用过的并且要去复活的学生
对于每个医院(d,q),由第i天的结束节点向第i+d+1天的开始节点连容量为inf,费用为q的边,表示把这些学生复活
然后跑遍费用流即可,如果最大流=总共所需学生数量则有解,否则无解
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 105
 7 #define maxm 20300
 8 #define inf 1061109567
 9 using namespace std;
10 char ch;
11 bool ok;
12 void read(int &x){
13     ok=0;
14     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
15     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
16     if (ok) x=-x;
17 }
18 int T,n,m,k,x,y,sum;
19 struct costflow{
20     int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
21     int dis[maxn],tmp,totflow,totcost,sla[maxn],head,tail,list[maxn],path[maxn];
22     bool bo[maxn];
23     void init(){s=0,t=(n<<1)+1,tot=1,memset(now,0,sizeof(now));}
24     void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;}
25     void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,0,-d);}
26     int dfs(int u,int rest,int totval){
27         if (u==t){totcost+=rest*totval;return rest;}
28         int ans=0; bo[u]=1;
29         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
30             if (val[p]&&!bo[v]){
31                 int t=dis[u]+cost[p]-dis[v];
32                 if (!t){
33                     int d=dfs(v,min(rest,val[p]),totval+cost[p]);
34                     val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
35                 }
36                 else sla[v]=min(sla[v],t);
37             }
38         return ans;
39     }
40     bool relax(){
41         int d=inf;
42         for (int u=s;u<=t;u++) if (!bo[u]) d=min(d,sla[u]);
43         if (d==inf) return false;
44         for (int u=s;u<=t;u++) if (!bo[u]) dis[u]+=d;
45         return true;    
46     }
47     void work(){
48         memset(dis,0,sizeof(dis)),totflow=totcost=0;
49         do{
50             memset(sla,63,sizeof(sla));
51             do{
52                 memset(bo,0,sizeof(bo));
53                 tmp=dfs(s,inf,0),totflow+=tmp;
54             }while (tmp);
55         }while (relax());
56     }
57 }f;
58 int main(){
59     int Case=0;
60     for (read(T);T;T--){
61         read(n),read(m),read(k),f.init(),sum=0,Case++;
62         for (int i=1;i<=n;i++) read(x),sum+=x,f.add(i,f.t,x,0),f.add(f.s,i+n,x,0);
63         for (int i=1;i<n;i++) f.add(i,i+1,inf,0);
64         for (int i=1;i<=m;i++) read(x),read(y),f.add(f.s,1,x,y);
65         for (int i=1;i<=k;i++){
66             read(x),read(y);
67             for (int j=1;j<=n-x-1;j++) f.add(j+n,j+x+1,inf,y);
68         }
69         f.work();
70         printf("Case %d: ",Case);
71         if (f.totflow==sum) printf("%d\n",f.totcost);
72         else puts("impossible");
73     }
74     return 0;
75 }

 

bzoj3280: 小R的烦恼

标签:

原文地址:http://www.cnblogs.com/chenyushuo/p/5152605.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!