2424. [HAOI2010]订货【费用流】

Description

某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。

Input

第1行:n, m, S (0<=n<=50, 0<=m<=10, 0<=S<=10000)
第2行:U1 , U2 , ... , Ui , ... , Un (0<=Ui<=10000)
第3行:d1 , d2 , ..., di , ... , dn (0<=di<=100)

Output

只有1行,一个整数,代表最低成本

Sample Input

3 1 1000
2 4 8
1 2 4

Sample Output

34
 
一道比餐巾计划垃圾到不知道到哪里去的题
(好吧感觉和餐巾计划是一个题)
S---每一天 ,INF,当日单价
每一天---T,当日需求,0
每一天---下一天,S,m
啊做水题真爽
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<queue>
 6 #define id(x,y) (x-1)*m+y
 7 #define N (10000+10)
 8 #define M (1000000+10)
 9 using namespace std;
10 bool used[N];
11 int n,m,S,s,e,u[101],d[101];
12 int num_edge,head[N];
13 int dis[N],INF,pre[N];
14 queue<int>q;
15 struct node
16 {
17     int to,next,Flow,Cost;
18 } edge[M*2];
19 
20 void add(int u,int v,int l,int c)
21 {
22     edge[++num_edge].to=v;
23     edge[num_edge].next=head[u];
24     edge[num_edge].Flow=l;
25     edge[num_edge].Cost=c;
26     head[u]=num_edge;
27 }
28 
29 bool Spfa(int s,int e)
30 {
31     memset(dis,0x7f,sizeof(dis));
32     memset(pre,-1,sizeof(pre));
33     dis[s]=0;
34     used[s]=true;
35     q.push(s);
36     while (!q.empty())
37     {
38         int x=q.front();
39         q.pop();
40         for (int i=head[x]; i!=0; i=edge[i].next)
41             if (dis[x]+edge[i].Cost<dis[edge[i].to] && edge[i].Flow>0)
42             {
43                 dis[edge[i].to]=dis[x]+edge[i].Cost;
44                 pre[edge[i].to]=i;
45                 if (!used[edge[i].to])
46                 {
47                     used[edge[i].to]=true;
48                     q.push(edge[i].to);
49                 }
50             }
51         used[x]=false;
52     }
53     return dis[e]!=INF;
54 }
55 
56 int MCMF(int s,int e)
57 {
58     int Fee=0;
59     while (Spfa(s,e))
60     {
61         int d=INF;
62         for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to)
63             d=min(d,edge[pre[i]].Flow);
64         for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to)
65         {
66             edge[pre[i]].Flow-=d;
67             edge[((pre[i]-1)^1)+1].Flow+=d;
68         }
69         Fee+=d*dis[e];
70     }
71     return Fee;
72 }
73 
74 int main()
75 {
76     memset(&INF,0x7f,sizeof(INF));
77     s=0,e=10001;
78     scanf("%d%d%d",&n,&m,&S);
79     for (int i=1; i<=n; ++i)
80         scanf("%d",&u[i]);
81     for (int i=1; i<=n; ++i)
82         scanf("%d",&d[i]);
83     for (int i=1; i<=n; ++i)
84     {
85         add(s,i,INF,d[i]);
86         add(i,s,0,-d[i]);
87         add(i,e,u[i],0);
88         add(e,i,0,0);
89         if (i==n) break;
90         add(i,i+1,S,m);
91         add(i+1,i,0,-m);
92     }
93     printf("%d",MCMF(s,e));
94 }
posted @ 2018-03-31 15:13  Refun  阅读(137)  评论(0编辑  收藏  举报