建图很巧妙。
1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N=4010;
5 const ll oo=3e18;
6 int tot,n,m,f,s,p,super_s,super_t;
7 struct Edge{
8 int from,to;
9 ll flow,cap,cost;
10 Edge(int _from=0,int _to=0,ll _flow=0,ll _cap=0,ll _cost=0):from(_from),to(_to),flow(_flow),cap(_cap),cost(_cost){}
11 };
12 Edge edge[40010];
13 vector<int>point[N];
14 int edge_tot;
15 void add_edge(int f,int t,ll c,ll cc){
16 edge[edge_tot]=Edge(f,t,0,c,cc);
17 point[f].push_back(edge_tot++);
18 edge[edge_tot]=Edge(t,f,0,0,-cc);
19 point[t].push_back(edge_tot++);
20 return;
21 }
22 ll dis[N];
23 int pre[N];
24 bool inq[N];
25 bool spfa(){
26 memset(dis,127/2,sizeof(dis));
27 queue<int>q;
28 q.push(super_s);
29 dis[super_s]=0,inq[super_s]=1;
30 int x;
31 while(!q.empty()){
32 x=q.front();q.pop();
33 inq[x]=0;
34 for(int i=0;i<point[x].size();i++){
35 Edge& e=edge[point[x][i]];
36 if(e.cap<=e.flow) continue;
37 if(dis[e.to]>dis[x]+e.cost){
38 dis[e.to]=dis[x]+e.cost,pre[e.to]=point[x][i];
39 if(!inq[e.to]){q.push(e.to);inq[e.to]=1;}
40 }
41 }
42 }
43 return dis[super_t]<oo;
44 }
45 ll mincostflow(){
46 int now;
47 ll minf,ans=0;
48 while(spfa()){
49 minf=oo,now=super_t;
50 while(now!=super_s) minf=min(minf,edge[pre[now]].cap-edge[pre[now]].flow),now=edge[pre[now]].from;
51 now=super_t,ans+=1LL*minf*dis[super_t];
52 while(now!=super_s) edge[pre[now]].flow+=minf,edge[pre[now]^1].flow-=minf,now=edge[pre[now]].from;
53 }
54 return ans;
55 }
56 int main(){
57 int t1;
58 scanf("%d",&tot);
59 super_s=tot+tot+1,super_t=tot+tot+2;
60 for(int i=1;i<=tot;i++){
61 scanf("%d",&t1);
62 add_edge(super_s,i,t1,0);
63 add_edge(i+tot,super_t,t1,0);
64 if(i<tot) add_edge(i+tot,i+tot+1,oo,0);
65 }
66 scanf("%d%d%d%d%d",&p,&m,&f,&n,&s);
67 for(int i=1;i<=tot-m;i++) add_edge(i,i+m+tot,oo,f);
68 for(int i=1;i<=tot-n;i++) add_edge(i,i+n+tot,oo,s);
69 for(int i=1;i<=tot;i++) add_edge(super_s,i+tot,oo,p);
70 printf("%lld",mincostflow());
71 return 0;
72 }