LOJ #6008. 「网络流 24 题」餐巾计划

#6008. 「网络流 24 题」餐巾计划 

题目描述

一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同。假设第 i ii 天需要 ri r_iri​​ 块餐巾。餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分;或者把旧餐巾送到快洗部,洗一块需 M MM天,其费用为 F FF 分;或者送到慢洗部,洗一块需 N NN 天,其费用为 S SS 分(S<F S < FS<F)。

每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

试设计一个算法为餐厅合理地安排好 n nn 天中餐巾使用计划,使总的花费最小。

输入格式

第 1 11 行有 6 66 个正整数 n nn、P PP、M MM、F FF、N NN、S SS。

n nn 是要安排餐巾使用计划的天数,P PP 是每块新餐巾的费用,M MM 是快洗部洗一块餐巾需用天数,F FF 是快洗部洗一块餐巾需要的费用,N NN 是慢洗部洗一块餐巾需用天数,S SS 是慢洗部洗一块餐巾需要的费用。

接下来的 n nn 行是餐厅在相继的 n nn 天里,每天需用的餐巾数。

输出格式

输出餐厅在相继的 n nn 天里使用餐巾的最小总花费。

样例

样例输入

3 10 2 3 3 2
5
6
7

样例输出

145

数据范围与提示

1≤n≤1000 1 \leq n \leq 10001n1000

 

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 const int N = 5010;
 7 const int INF = 1e9;
 8 
 9 struct Edge{
10     int u,v,f,c,nxt;
11     Edge(){}
12     Edge(int a,int b,int flow,int cost,int nt) { //-
13         u = a;v = b;f = flow;c = cost;nxt = nt;
14     }
15 }e[100100];
16 int head[N],dis[N],q[100100],pre[N];
17 bool vis[N];
18 int L,R,S,T,tot = 1,Mc,Mf;
19 
20 inline char nc() {
21     static char buf[10010],*p1 = buf,*p2 = buf;
22     return p1==p2&&(p2=(p1=buf)+fread(buf,1,10000,stdin),p1==p2)?EOF:*p1++;    
23 }
24 int read() {
25     int x = 0,f = 1;char ch = nc();
26     for (; ch<'0'||ch>'9'; ch=nc()) if (ch=='-')f=-1;
27     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
28     return x*f;
29 }
30 void add_edge(int u,int v,int f,int c) {
31     e[++tot] = Edge(u,v,f,c,head[u]);head[u] = tot;
32     e[++tot] = Edge(v,u,0,-c,head[v]);head[v] = tot;
33 }
34 bool spfa() {
35     for (int i=1; i<=T; ++i) vis[i]=false,dis[i]=INF;
36     L = 1;R = 0;
37     dis[S] = 0;
38     q[++R] = S;vis[S] = true;pre[S] = 0;
39     while (L <= R) {
40         int u = q[L++];
41         for (int i=head[u]; i; i=e[i].nxt) {
42             int v = e[i].v;
43             if (dis[v]>dis[u]+e[i].c && e[i].f > 0) {
44                 dis[v] = dis[u] + e[i].c;
45                 pre[v] = i;
46                 if (!vis[v]) q[++R] = v,vis[v] = true;
47             }
48         }
49         vis[u] = false;
50     }
51     return dis[T]!=INF;
52 }
53 void mcf() {
54     int zf = INF;
55     for (int i=T; i!=S; i=e[pre[i]].u) 
56         zf = min(zf,e[pre[i]].f);
57     for (int i=T; i!=S; i=e[pre[i]].u) 
58         e[pre[i]].f -= zf,e[pre[i]^1].f += zf;
59     Mf += zf;Mc += dis[T]*zf;
60 }
61 int main() {
62     int n = read(),c = read(),kt = read(),kc = read(),mt = read(),mc = read();
63     S = n*2+1;T = n*2+2;
64     for (int t,i=1; i<=n; ++i) {
65         t = read();
66         add_edge(S,i,t,0);
67         add_edge(i+n,T,t,0);
68         add_edge(S,i+n,INF,c);
69         if (i+kt<=n) add_edge(i,i+n+kt,INF,kc);
70         if (i+mt<=n) add_edge(i,i+n+mt,INF,mc);
71         if (i+1<=n) add_edge(i,i+1,INF,0);
72     }
73     while (spfa()) mcf();
74     printf("%d",Mc);
75     return 0;
76 }

 

posted @ 2018-03-10 20:05  MJT12044  阅读(254)  评论(0编辑  收藏  举报