zoukankan      html  css  js  c++  java
  • [HNOI 2001]软件开发

    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

    题解

    经典构图题。

    将每一天拆成两个点$i$,$i’$,

    加如下$6$条边:

    $(sta, i, ni, f)$——在第$i$天可以买至多$ni$个餐巾,每块$f$分;

    $(i, fin, ni, 0)$——第$i$天要用$ni$块餐巾;

    $(sta, i’, ni, 0)$——第$i$天用剩的$ni$块旧餐巾;

    $(i’, i+a+1, ∞, fa)$——第$i$天的旧餐巾送到快洗部,每块$fa$分;

    $(i’, i+b+1, ∞, fb)$——第$i$天的旧餐巾送到慢洗部,每块$fb$分;

    $(i’, i’+1, ∞, 0)$——第$i$天的旧餐巾可以留到第$i+1$天再处理;

    求一次最小费用流即为结果。

     1 #include <set>
     2 #include <map>
     3 #include <ctime>
     4 #include <cmath>
     5 #include <queue>
     6 #include <stack>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <string>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 #define LL long long
    15 #define Max(a, b) ((a) > (b) ? (a) : (b))
    16 #define Min(a, b) ((a) < (b) ? (a) : (b))
    17 using namespace std;
    18 const int N = 2e3;
    19 const int INF = ~0u>>1;
    20 
    21 int n,a,b,f,fa,fb,ni;
    22 struct tt{
    23     int to, cost, next, cap;
    24 }edge[N*6+5];
    25 int path[N+5], top = -1;
    26 void Add(int u, int v, int cap, int cost);
    27 int sta, fin;
    28 int min_cost_flow();
    29 int SPFA();
    30 
    31 int main(){
    32     memset(path, -1, sizeof(path));
    33     scanf("%d%d%d%d%d%d", &n, &a, &b, &f, &fa, &fb);
    34     sta = 0, fin = 2*n+1;
    35     for (int i = 1; i <= n; i++){
    36       scanf("%d", &ni);
    37       Add(sta, i, ni, f);
    38       Add(i, fin, ni, 0);
    39       Add(sta, i+n, ni, 0);
    40       if (i+a+1 <= n) Add(i+n, i+a+1, INF, fa);
    41       if (i+b+1 <= n) Add(i+n, i+b+1, INF, fb);
    42       if (i+1 <= n) Add(i+n, i+1+n, INF, 0);
    43     }
    44     printf("%d
    ", min_cost_flow());
    45     return 0;
    46 }
    47 
    48 void Add(int u, int v, int cap, int cost){
    49     edge[++top].to = v;
    50     edge[top].cost = cost;
    51     edge[top].cap = cap;
    52     edge[top].next = path[u];
    53     path[u] = top;
    54     edge[++top].to = u;
    55     edge[top].cost = -cost;
    56     edge[top].cap = 0;
    57     edge[top].next = path[v];
    58     path[v] = top;
    59 }
    60 int min_cost_flow(){
    61     int tolcost = 0;
    62     int tmp;
    63     while (tmp = SPFA()) tolcost += tmp;
    64     return tolcost;
    65 }
    66 int SPFA(){
    67     int dist[N+5];
    68     memset(dist, 127/3, sizeof(dist)); dist[sta] = 0; dist[fin] = INF;
    69     bool vis[N+5] = {0}; vis[sta] = 1;
    70     queue<int>Q;
    71     while (!Q.empty()) Q.pop();
    72     Q.push(sta);
    73     int pre[N+5] = {0};
    74     while (!Q.empty()){
    75       int u = Q.front(); Q.pop(); vis[u]=0;
    76       for (int i = path[u]; i != -1; i = edge[i].next){
    77           int v = edge[i].to;
    78           if (dist[v] > dist[u]+edge[i].cost && edge[i].cap > 0){
    79             dist[v] = dist[u]+edge[i].cost;
    80             pre[v] = i;
    81             if (!vis[v]){
    82                 vis[v] = 1;
    83                 Q.push(v);
    84             }
    85           }
    86       }
    87     }
    88     if (dist[fin] == INF) return 0;
    89     int minflow = INF;
    90     for (int i = fin; i != sta; i = edge[pre[i]^1].to)
    91       minflow = Min(minflow, edge[pre[i]].cap);
    92     for (int i = fin; i != sta; i = edge[pre[i]^1].to)
    93       edge[pre[i]].cap -= minflow,
    94       edge[pre[i]^1].cap += minflow;
    95     return dist[fin]*minflow;
    96 }
  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7463215.html
Copyright © 2011-2022 走看看