1. 程式人生 > >[HNOI2001]軟件開發

[HNOI2001]軟件開發

方式 next soft reg gpo strong queue region sizeof

題目描述

某軟件公司正在規劃一項n天的軟件開發計劃,根據開發計劃第i天需要ni個軟件開發人員,為了提高軟件開發人員的效率,公司給軟件人員提供了很多的 服務,其中一項服務就是要為每個開發人員每天提供一塊消毒毛巾,這種消毒毛巾使用一天後必須再做消毒處理後才能使用。消毒方式有兩種,A種方式的消毒需要 a天時間,B種方式的消毒需要b天(b>a),A種消毒方式的費用為每塊毛巾fA, B種消毒方式的費用為每塊毛巾fB,而買一塊新毛巾的費用為f(新毛巾是已消毒的,當天可以使用);而且f>fA>fB。公司經理正在規劃在 這n天中,每天買多少塊新毛巾、每天送多少塊毛巾進行A種消毒和每天送多少塊毛巾進行B種消毒。當然,公司經理希望費用最低。

你的任務就是:為該軟件公司計劃每天買多少塊毛巾、每天多少塊毛巾進行A種消毒和多少毛巾進行B種消毒,使公司在這項n天的軟件開發中,提供毛巾服務的總費用最低。

輸入輸出格式

輸入格式:

第1行為n,a,b,f,fA,fB.

第2行為n1,n2,……,nn. (註:1≤f,fA,fB≤60,1≤n≤1000)

輸出格式:

最少費用

輸入輸出樣例

輸入樣例#1: 復制
4  1  2  3  2  1                         
8  2  1  6  
輸出樣例#1: 復制
38

建立附加源點和匯點S和T


1. 源點到第i天的入點連容量ni費用為0的邊


2. 第i天的出點到匯點連容量ni費用為0的邊


3. 源點到第i天的出點連容量為INF費用為f的邊


4. 第i天的入點到第i+a+1(i+b+1)天的出點連容量為INF費用為fa(fb)的邊


5. 第i天的入點到第i+1天的入點連容量為INF費用為0的邊

S連出的邊表示這一天會剩下ni個臟布,連向T表示這一天要用ni個布

一天用完的ni個布,可以由a(b)方式給第i+a+1(i+b+1)天,也可以不洗,留到下一天再洗

 1 #include<iostream>
 2 #include<cstdio>
 3
#include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 struct Node 8 { 9 int next,to,c,dis,u; 10 }edge[200001]; 11 int num=1,head[5001],inf=2e9,dis[5001],pre[5001]; 12 long long ans; 13 int d[5001],n,a,b,fa,fb,f; 14 bool vis[5001]; 15 void add(int u,int v,int c,int d) 16 { 17 num++; 18 edge[num].next=head[u]; 19 head[u]=num; 20 edge[num].to=v; 21 edge[num].dis=d; 22 edge[num].c=c; 23 edge[num].u=u; 24 num++; 25 edge[num].next=head[v]; 26 head[v]=num; 27 edge[num].to=u; 28 edge[num].dis=-d; 29 edge[num].c=0; 30 edge[num].u=v; 31 } 32 bool SPFA() 33 {int INF,i; 34 memset(pre,-1,sizeof(pre)); 35 memset(vis,0,sizeof(vis)); 36 memset(dis,127/3,sizeof(dis)); 37 INF=dis[0]; 38 dis[0]=0; 39 queue<int>Q; 40 Q.push(0); 41 while (Q.empty()==0) 42 { 43 int u=Q.front(); 44 Q.pop(); 45 vis[u]=0; 46 for (i=head[u];i;i=edge[i].next) 47 { 48 int v=edge[i].to; 49 if (edge[i].c&&dis[v]>dis[u]+edge[i].dis) 50 { 51 dis[v]=dis[u]+edge[i].dis; 52 pre[v]=i; 53 if (vis[v]==0) 54 { 55 vis[v]=1; 56 Q.push(v); 57 } 58 } 59 } 60 } 61 if (dis[2*n+1]==INF) return 0; 62 return 1; 63 } 64 void change() 65 {int i; 66 int T=2*n+1; 67 int minf=inf; 68 for (i=pre[T];i!=-1;i=pre[edge[i].u]) 69 { 70 minf=min(minf,edge[i].c); 71 } 72 for (i=pre[T];i!=-1;i=pre[edge[i].u]) 73 { 74 edge[i].c-=minf; 75 edge[i^1].c+=minf; 76 } 77 ans+=minf*dis[T]; 78 } 79 int main() 80 {int i; 81 cin>>n>>a>>b>>f>>fa>>fb; 82 for (i=1;i<=n;i++) 83 scanf("%d",&d[i]); 84 for (i=1;i<=n;i++) 85 add(0,i,d[i],0),add(i+n,2*n+1,d[i],0),add(0,i+n,inf,f); 86 for (i=1;i<=n-1;i++) 87 add(i,i+1,inf,0); 88 for (i=1;i<=n;i++) 89 { 90 if (i+a+1<=n) add(i,i+a+1+n,inf,fa); 91 if (i+b+1<=n) add(i,i+b+1+n,inf,fb); 92 } 93 while (SPFA()) change(); 94 cout<<ans; 95 }

[HNOI2001]軟件開發