bzoj2424: [HAOI2010]订货(费用流)

2424: [HAOI2010]订货

题目:传送门 

 


 

 

题解:

   做多了最小割,做一下费用流练手

   其实很容易就看出来是费用流啊,伏地魔肉老师用单调队列ORZ

   st直接连每个月,流量无限(随便买,花钱而已),费用就是给出来的

   然后因为可以贮存嘛,那就第i个月连第i+1个月,流量为S(仓库容量),费用为m就OK

   最后就是卖出去咯,第i个月连ed流量为需要的,费用为0

   难受,打个spfa忘记出队列...

    


 

 

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define inf 999999999
 7 using namespace std;
 8 struct node
 9 {
10     int x,y,c,d,next,other;
11 }a[1100];int len,last[110];
12 void ins(int x,int y,int c,int d)
13 {
14     int k1,k2;
15     k1=++len;
16     a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;
17     a[len].next=last[x];last[x]=len;
18     
19     k2=++len;
20     a[len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d;
21     a[len].next=last[y];last[y]=len;
22     
23     a[k1].other=k2;
24     a[k2].other=k1;
25 }
26 int list[11000],la[11000],d[11000],st,ed,n,m,head,tail,ans,S;
27 bool v[11000];
28 bool spfa()
29 {
30     for(int i=1;i<=ed;i++)d[i]=inf;
31     memset(v,false,sizeof(v));memset(la,0,sizeof(la));
32     list[1]=st;d[st]=0;v[st]=true;head=1;tail=2;
33     while(head!=tail)
34     {
35         int x=list[head];
36         for(int k=last[x];k;k=a[k].next)
37         {
38             int y=a[k].y;
39             if(a[k].c>0 && d[y]>d[x]+a[k].d)
40             {
41                 d[y]=d[x]+a[k].d;la[y]=k;
42                 if(v[y]==false)
43                 {
44                     v[y]=true;
45                     list[tail++]=y;
46                     if(tail==ed+1)tail=1;
47                 }
48             }
49         }
50         head++;if(head==ed+1)head=1;
51         v[x]=false;
52     }
53     if(d[ed]==inf)return false;
54     return true;
55 }
56 int g_f()
57 {
58     int x,k,f=inf,ans=0;
59     x=ed;while(x!=st){k=la[x];f=min(f,a[k].c);x=a[k].x;}
60     x=ed;while(x!=st){k=la[x];ans+=f*a[k].d;a[k].c-=f;a[a[k].other].c+=f;x=a[k].x;}
61     return ans;
62 }
63 int A[110],B[110];
64 int main()
65 {
66     scanf("%d%d%d",&n,&m,&S);len=0;memset(last,0,sizeof(last));st=n+1,ed=st+1;
67     for(int i=1;i<=n;i++)scanf("%d",&A[i]);
68     for(int i=1;i<=n;i++)scanf("%d",&B[i]);
69     for(int i=1;i<=n;i++)ins(st,i,inf,B[i]);
70     for(int i=1;i<=n;i++){if(i!=n)ins(i,i+1,S,m);ins(i,ed,A[i],0);}
71     int ans=0;while(spfa())ans+=g_f();
72     printf("%d\n",ans);
73     return 0;
74 }

 

posted @ 2018-03-28 11:49  CHerish_OI  阅读(122)  评论(0编辑  收藏  举报