【BZOJ 1221】 1221: [HNOI2001] 软件开发 (最小费用流)
1221: [HNOI2001] 软件开发
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1581 Solved: 891Description
某软件公司正在规划一项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
【分析】
网络流24题经典题,我把向下那个变成了另一边的,好理解一点。
传送门: http://www.cnblogs.com/Konjakmoyu/p/6030813.html
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define INF 0xfffffff 9 #define Maxn 1010 10 11 int mymin(int x,int y) {return x<y?x:y;} 12 13 struct node 14 { 15 int x,y,f,c,next,o; 16 }t[Maxn*20]; 17 int first[Maxn*4],len; 18 19 void ins(int x,int y,int f,int c) 20 { 21 t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c; 22 t[len].next=first[x];first[x]=len;t[len].o=len+1; 23 t[++len].x=y;t[len].y=x;t[len].f=0;t[len].c=-c; 24 t[len].next=first[y];first[y]=len;t[len].o=len-1; 25 } 26 27 queue<int > q; 28 bool inq[Maxn*4]; 29 int pre[Maxn*4],flow[Maxn*4],dis[Maxn*4]; 30 int st,ed; 31 bool bfs() 32 { 33 while(!q.empty()) q.pop(); 34 memset(inq,0,sizeof(inq)); 35 for(int i=1;i<=ed;i++) dis[i]=-1; 36 inq[st]=1;dis[st]=0;flow[st]=INF; 37 q.push(st); 38 while(!q.empty()) 39 { 40 int x=q.front(); 41 for(int i=first[x];i;i=t[i].next) if(t[i].f>0) 42 { 43 int y=t[i].y; 44 if(dis[y]==-1||dis[y]>dis[x]+t[i].c) 45 { 46 dis[y]=dis[x]+t[i].c; 47 pre[y]=i; 48 flow[y]=mymin(flow[x],t[i].f); 49 if(!inq[y]) 50 { 51 q.push(y); 52 inq[y]=1; 53 } 54 } 55 }q.pop();inq[x]=0; 56 } 57 if(dis[ed]==-1) return 0; 58 return 1; 59 } 60 61 int max_flow() 62 { 63 int sum=0; 64 while(bfs()) 65 { 66 int x=ed,a=flow[ed]; 67 sum+=flow[ed]*dis[ed]; 68 while(x!=st) 69 { 70 t[pre[x]].f-=a; 71 t[t[pre[x]].o].f+=a; 72 x=t[pre[x]].x; 73 } 74 } 75 printf("%d\n",sum); 76 } 77 78 void output() 79 { 80 for(int i=1;i<=len;i+=2) 81 { 82 printf("%d -> %d %d %d\n",t[i].x,t[i].y,t[i].f,t[i].c); 83 }printf("\n"); 84 } 85 86 int nd[Maxn]; 87 88 int main() 89 { 90 int n,a,b,fc,fA,fB; 91 scanf("%d%d%d%d%d%d",&n,&a,&b,&fc,&fA,&fB); 92 for(int i=1;i<=n;i++) scanf("%d",&nd[i]); 93 st=2*n+1,ed=st+1; 94 for(int i=1;i<=n;i++) ins(st,n+i,INF,fc); 95 for(int i=1;i<n;i++) ins(i+n,i+1+n,INF,0); 96 for(int i=1;i<=n;i++) ins(st,i,nd[i],0); 97 for(int i=1;i<=n;i++) ins(i+n,ed,nd[i],0); 98 for(int i=1;i<=n-a-1;i++) ins(i,i+a+1+n,INF,fA); 99 for(int i=1;i<=n-b-1;i++) ins(i,i+b+1+n,INF,fB); 100 // output(); 101 max_flow(); 102 return 0; 103 }
2017-03-28 11:28:49