1221. [HNOI2001]软件开发【费用流】

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

上个题做了一个餐巾计划的弱化版……这个题直接就是餐巾计划(近乎原题了)
只不过餐巾计划餐巾洗完了当天就能用,这个要往后延一天

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<queue>
  6 #define LL long long
  7 #define MAXN (10000+10)
  8 #define MAXM (2000000+10)
  9 using namespace std;
 10 queue<LL>q;
 11 LL n,m,k,s=0,e=9999,Ans,Fee;
 12 LL num_edge,head[MAXN],dis[MAXN];
 13 LL Need[MAXN],pre[MAXN],INF;
 14 bool used[MAXN];
 15 struct node
 16 {
 17     LL to,next,Flow,Cost;
 18 } edge[MAXM*2];
 19 
 20 void add(LL u,LL v,LL l,LL 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(LL s,LL e)
 30 {
 31     memset(pre,-1,sizeof(pre));
 32     memset(dis,0x7f,sizeof(dis));
 33     q.push(s);
 34     dis[s]=0;
 35     used[s]=true;
 36     while (!q.empty())
 37     {
 38         LL x=q.front();
 39         q.pop();
 40         for (int i=head[x]; i!=0; i=edge[i].next)
 41             if (edge[i].Flow>0 && dis[x]+edge[i].Cost<dis[edge[i].to])
 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 void MCMF(LL s,LL e)
 57 {
 58     LL Ans=0,Fee=0;
 59     while (Spfa(s,e))
 60     {
 61         LL 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         Ans+=d;
 70         Fee+=d*dis[e];
 71     }
 72     printf("%lld",Fee);
 73 }
 74 
 75 int main()
 76 {
 77     memset(&INF,0x7f,sizeof(INF));
 78     scanf("%lld",&n);
 79     LL New,FD,FC,SD,SC;
 80     scanf("%lld%lld%lld%lld%lld",&FD,&SD,&New,&FC,&SC);
 81     for (LL i=1; i<=n; ++i)
 82     {
 83         scanf("%lld",&Need[i]);
 84         add(s,(i-1)*2+1,Need[i],0);
 85         add((i-1)*2+1,s,0,0);
 86         add((i-1)*2+2,e,Need[i],0);
 87         add(e,(i-1)*2+2,0,0);
 88         if (i<n)
 89         {
 90             add((i-1)*2+1,i*2+1,INF,0);
 91             add(i*2+1,(i-1)*2+1,0,0);
 92         }
 93     }
 94     for (int i=1; i<=n; ++i)
 95     {
 96         add(s,(i-1)*2+2,INF,New);
 97         add((i-1)*2+2,s,0,-New);
 98 
 99         add((i-1)*2+1,(i+FD)*2+2,INF,FC);
100         add((i+FD)*2+2,(i-1)*2+1,0,-FC);
101 
102         add((i-1)*2+1,(i+SD)*2+2,INF,SC);
103         add((i+SD)*2+2,(i-1)*2+1,0,-SC);
104 
105     }
106     MCMF(s,e);
107 }
原文地址:https://www.cnblogs.com/refun/p/8682334.html