zoukankan      html  css  js  c++  java
  • 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
    ", minCost());
    128 }

    @Author: YouSiki

  • 相关阅读:
    C# 中的高性能计时器(Daniel Strigl著,野比译)(转)
    C#中SerialPort类 随笔
    迭代器
    枚举数与可枚举类型(笔记)
    jQuery的关注与学习
    敏捷开发的4句宣言 大数据
    bat脚本
    c++动态库中回调函数使用
    C++中遍历lua table
    vs2010编译release版本却依赖debug版本库msvcrd100.dll
  • 原文地址:https://www.cnblogs.com/yousiki/p/6243967.html
Copyright © 2011-2022 走看看