BZOJ 1221: [HNOI2001] 软件开发

1221: [HNOI2001] 软件开发

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1428  Solved: 791
[Submit][Status][Discuss]

Description

某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

Input

第1行为n,a,b,f,fA,fB. 第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

Output

最少费用

Sample Input

4 1 2 3 2 1
8 2 1 6

Sample Output

38

HINT

 

Source

 
[Submit][Status][Discuss]

 

最小费用最大流,各种调代码。

 

把每一天拆点,分为Xi和Yi。可以理解X为未消毒,Y为已消毒。

源点向Xi供应Ni个费用为0的流量,代表每天产生的用过的毛巾。

Yi向汇点连容量Ni的费用为0的边,代表每天使用的毛巾。

源点向Yi连费用为F的边,容量无穷,代表可以新购毛巾。

Xi向Yi+A+1连费用为Fa的边,代表可以在i时送去消毒,i+A+1时使用;B同理。

Xi向Xi+1连边,代表今天的脏毛巾可以留着回头再拿来洗。

 

  1 #include <bits/stdc++.h>
  2 
  3 inline int get_c(void)
  4 {
  5     static const int siz = 1024;
  6 
  7     static char buf[siz];
  8     static char *head = buf + siz;
  9     static char *tail = buf + siz;
 10 
 11     if (head == tail)
 12         fread(head = buf, 1, siz, stdin);
 13 
 14     return *head++;
 15 }
 16 
 17 inline int get_i(void)
 18 {
 19     register int ret = 0;
 20     register int neg = false;
 21     register int bit = get_c();
 22 
 23     for (; bit < 48; bit = get_c())
 24         if (bit == '-')neg ^= true;
 25 
 26     for (; bit > 47; bit = get_c())
 27         ret = ret * 10 + bit - 48;
 28 
 29     return neg ? -ret : ret;
 30 }
 31 
 32 const int inf = 2e9;
 33 const int maxn = 200005;
 34 
 35 int n, a, b, f, c, d;
 36 
 37 int s, t;
 38 int edges;
 39 int hd[maxn];
 40 int to[maxn];
 41 int fl[maxn];
 42 int vl[maxn];
 43 int nt[maxn];
 44 
 45 inline void add(int u, int v, int f, int w) {
 46     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; vl[edges] = +w; hd[u] = edges++;
 47     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; vl[edges] = -w; hd[v] = edges++;
 48 }
 49 
 50 int dis[maxn];
 51 int pre[maxn];
 52 
 53 inline bool bfs(void) {
 54     static int que[maxn];
 55     static int inq[maxn];
 56     static int head, tail;
 57     
 58     for (int i = s; i <= t; ++i)dis[i] = inf;
 59     memset(inq, 0, sizeof(inq));
 60     que[tail++] = s;
 61     pre[s] = -1;
 62     dis[s] = 0;
 63     inq[s] = 1;
 64     
 65     while (head != tail) {
 66         int u = que[head++], v; inq[u] = 0;
 67         if (head == maxn)head = 0;
 68         for (int i = hd[u]; ~i; i = nt[i])
 69             if (fl[i] && dis[v = to[i]] > dis[u] + vl[i]) {
 70                 dis[v] = dis[u] + vl[i];
 71                 pre[v] = i ^ 1;
 72                 if (!inq[v]) {
 73                     inq[que[tail++] = v];
 74                     if (tail == maxn)
 75                         tail = 0;
 76                 }
 77             }
 78     }
 79     
 80     return dis[t] < inf;
 81 }
 82 
 83 inline int minCost(void) {
 84     int cost = 0;
 85     
 86     while (bfs()) {
 87         int flow = inf;
 88         
 89         for (int i = pre[t]; ~i; i = pre[to[i]])
 90             flow = std::min(flow, fl[i ^ 1]);
 91             
 92         for (int i = pre[t]; ~i; i = pre[to[i]])
 93             fl[i] += flow, fl[i ^ 1] -= flow;
 94             
 95         cost += flow * dis[t];
 96     }
 97     
 98     return cost;
 99 }
100 
101 signed main(void)
102 {
103     memset(hd, -1, sizeof(hd));
104     
105     n = get_i();
106     a = get_i();
107     b = get_i();
108     f = get_i();
109     c = get_i();
110     d = get_i();
111     
112     s = 0, t = (n + 1) * 2 + 1;
113     
114     for (int i = 1; i <= n; ++i) {
115         int x = get_i();
116         add(s, i, x, 0);
117         add(i + n, t, x, 0);
118         add(s, i + n, inf, f);
119         if (i + 1 <= n)
120             add(i, i + 1, inf, 0);
121         if (i + a + 1 <= n)
122             add(i, i + a + 1 + n, inf, c);
123         if (i + b + 1 <= n)
124             add(i, i + b + 1 + n, inf, d);
125     }
126     
127     printf("%d\n", minCost());
128 }

 

@Author: YouSiki

 

posted @ 2017-01-03 10:24  YouSiki  阅读(174)  评论(0编辑  收藏  举报