The main idea is to recruit pilots, because of the N-day exercise so to recruit some pilots, the first day I need to recruit PI pilots, just started to have K pilots, pilots work a day after the M vacation plan, no vacation plan for work after TI days and start work again, get Si salary, In addition, you can choose to recruit pilots, starting from P days to recruit, recruitment needs to pay Q yuan.
Consider the origin of the pilot I day, divided into three sources, 1: the initial K Pilots 2: Recruited pilots 3: Vacation back pilots
For the first we can draw an edge from the source point S-> The first day, the capacity is K, the cost is 0. Then the first day to the first I+1 day to draw an edge, the capacity of INF, the cost is 0
For the second kind, we can draw an edge from the source point to the day I, the capacity is INF, the cost is Q
For the third kind we can divide the point of the ground I day into two X, X ', assuming that the current day of the pilot using vacation plan J and then restart the flight then a side X-(X+t[j]) ', the capacity of the INF, the cost of SJ, the code is as follows:
#include <bits/stdc++.h>using namespacestd;Const intINF =0x3f3f3f3f;Const intMAXN = -;structEdge {int from, to, cap, flow, cost;}; Vector<Edge>Edges;vector<int>G[MAXN];intINQUE[MAXN];//SPFAintD[MAXN];//SPFAintP[MAXN];//Enter arc numberintA[MAXN];//can improve the amountvoidInitintN) { for(intI=0; i<=n; i++) g[i].clear (); Edges.clear ();}voidAdd_edge (int from,intTo,intCapintCost ) {Edges.push_back (Edge) { from, to, Cap,0, cost}); Edges.push_back (Edge) {to, from,0,0, -Cost }); intm =edges.size (); g[ from].push_back (M-2); G[to].push_back (M-1);}BOOLSPFA (intSintTint&flow,Long Long&Cost ) {memset (d,0x3f,sizeof(d)); memset (Inque,0,sizeof(Inque)); D[s]=0; Inque[s] =1; A[s]= INF; D[s] =0; Queue<int>que; Que.push (s); while(!Que.empty ()) { intU =Que.front (); Que.pop (); Inque[u]=0; for(intI=0; I<g[u].size (); i++) {Edge e=Edges[g[u][i]]; if(E.cap>e.flow && d[e.to]>d[u]+e.cost) {D[e.to]= D[u] +E.cost; if(!inque[e.to]) Que.push (e.to), inque[e.to]=1; P[e.to]=G[u][i]; A[e.to]= Min (A[u], e.cap-E.flow); } } } if(D[t] = = INF)return false; Flow+=A[t]; Cost+= (Long Long) A[t] * (Long Long) d[t]; for(intu=t; U!=s; U=edges[p[u]]. from) {Edges[p[u]].flow+=A[t]; Edges[p[u]^1].flow-=A[t]; } return true;}intMCMF (intSintTLong Long&Cost ) { intFlow =0; Cost =0; while(SPFA (S, t, flow, cost)); returnflow;}intN, K;intpp[ -];intm, P, Q;ints[Ten], t[Ten];intMain () {intT; scanf ("%d", &T); while(t--) {scanf ("%d%d", &n, &k); intSUMPEO =0; for(intI=1; i<=n; i++) scanf ("%d", &pp[i]), sumpeo + =Pp[i]; scanf ("%d%d%d", &m, &p, &Q); for(intI=0; i<m; i++) scanf ("%d%d", &s[i], &T[i]); Init (2*n+2); intS =0, T =2*n+1; Add_edge (S),2K0); for(intI=1; i<=n; i++) {Add_edge (S),2*i-1, Pp[i],0); //people belong to K if(i+1<=n) Add_edge (2(In2* (i+1), INF,0); //Recruit if(i>=p) Add_edge (S),2*I, INF, Q); //people who come back from vacation for(intj=0; j<m; J + +)if(i+t[j]<=n) Add_edge (2*i-1,2* (i+T[j]), INF, s[j]); Add_edge (2*i, T, Pp[i],0); } Long LongCost ; intFlow =MCMF (S, T, cost); //printf ("flow =%d\n", flow); if(Flow! =sumpeo) printf ("No solution\n"); Elseprintf ("%lld\n", cost); } return 0;}
HDU5644 Minimum cost flow