1061: [Noi2008]志愿者招募 - BZOJ
Description
申奧成功后,布布經過不懈努力,終于成為奧組委下屬公司人力資源部門的主管。布布剛上任就遇到了一個難題:為即將啟動的奧運新項目招募一批短期志愿者。經過估算,這個項目需要N 天才能完成,其中第i 天至少需要Ai 個人。 布布通過了解得知,一共有M 類志愿者可以招募。其中第i 類可以從第Si 天工作到第Ti 天,招募費用是每人Ci 元。新官上任三把火,為了出色地完成自己的工作,布布希望用盡量少的費用招募足夠的志愿者,但這并不是他的特長!于是布布找到了你,希望你幫他設計一種最優的招募方案。
Input
第一行包含兩個整數N, M,表示完成項目的天數和可以招募的志愿者的種類。 接下來的一行中包含N 個非負整數,表示每天至少需要的志愿者人數。 接下來的M 行中每行包含三個整數Si, Ti, Ci,含義如上文所述。為了方便起見,我們可以認為每類志愿者的數量都是無限多的。
Output
僅包含一個整數,表示你所設計的最優方案的總費用。
Sample Input
3 3
2 3 4
1 2 2
2 3 5
3 3 2
Sample Output
14
HINT
招募第一類志愿者3名,第三類志愿者4名 30%的數據中,1 ≤ N, M ≤ 10,1 ≤ Ai ≤ 10; 100%的數據中,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,題目中其他所涉及的數據均 不超過2^31-1。
?
首先貼上別人的題解https://www.byvoid.com/blog/noi-2008-employee/
首先肯定都知道這個是線性規劃,可以用單純形法做,但是單純形法好像很少用一樣,反正我是不會
既然不會線性規劃,我們只好轉換成網絡流了,因為網絡流也是一種線性規劃我就不說什么了,弱菜表示完全想不到.....,線性規劃轉化為網絡流,完全不懂啊
1 const 2 maxn=1010; 3 maxm=40010; 4 inf=100000000; 5 var 6 a,flag,dis,f,first:array[0..maxn]of longint; 7 next,last,w,liu:array[0..maxm]of longint; 8 n,m,s,t,tot,time,ans,flow:longint; 9 10 procedure insert(u,v,f,l:longint); 11 begin 12 inc(tot); 13 last[tot]:=v; 14 next[tot]:=first[u]; 15 w[tot]:=f; 16 liu[tot]:=l; 17 first[u]:=tot; 18 inc(tot); 19 last[tot]:=u; 20 next[tot]:=first[v]; 21 w[tot]:=-f; 22 first[v]:=tot; 23 end; 24 25 procedure init; 26 var 27 i,j,x,y,z:longint; 28 begin 29 read(n,m); 30 tot:=1; 31 for i:=1 to n do 32 read(a[i]); 33 for i:=1 to m do 34 begin 35 read(x,y,z); 36 insert(x,y+1,z,inf); 37 end; 38 s:=0; 39 t:=n+2; 40 for i:=1 to n+1 do 41 begin 42 z:=a[i]-a[i-1]; 43 if z>0 then insert(s,i,0,z); 44 if z<0 then insert(i,t,0,-z); 45 if i>0 then insert(i,i-1,0,inf); 46 end; 47 end; 48 49 function dfs(x,flow:longint):longint; 50 var 51 i,d,min:longint; 52 begin 53 if x=t then 54 begin 55 inc(ans,flow*dis[t]); 56 exit(flow); 57 end; 58 i:=first[x]; 59 flag[x]:=time; 60 dfs:=0; 61 while i<>0 do 62 begin 63 d:=dis[x]+w[i]-dis[last[i]]; 64 min:=flow; 65 if min>liu[i] then min:=liu[i]; 66 if (min>0) and (d<f[last[i]]) then f[last[i]]:=d; 67 if (min>0) and (d=0) and (flag[last[i]]<>time) then 68 begin 69 d:=dfs(last[i],min); 70 inc(dfs,d); 71 dec(flow,d); 72 dec(liu[i],d); 73 inc(liu[i xor 1],d); 74 end; 75 if flow=0 then break; 76 i:=next[i]; 77 end; 78 end; 79 80 procedure work; 81 var 82 i,del:longint; 83 begin 84 repeat 85 inc(time); 86 for i:=s to t do 87 f[i]:=inf; 88 inc(flow,dfs(s,inf)); 89 del:=inf; 90 for i:=s to t do 91 if (flag[i]<>time) and (del>f[i]) then del:=f[i]; 92 if del=inf then break; 93 for i:=s to t do 94 if flag[i]<>time then inc(dis[i],del); 95 until false; 96 write(ans); 97 end; 98 99 var 100 q:array[0..maxn]of longint; 101 head,tail:longint; 102 103 procedure spfa; 104 var 105 i:longint; 106 begin 107 inc(time); 108 head:=1; 109 tail:=2; 110 fillchar(dis,sizeof(dis),1); 111 q[1]:=s; 112 dis[s]:=0; 113 while head<>tail do 114 begin 115 i:=first[q[head]]; 116 while i<>0 do 117 begin 118 if (liu[i]>0) and (dis[last[i]]>dis[q[head]]+w[i]) then 119 begin 120 if flag[last[i]]<>time then 121 begin 122 q[tail]:=last[i]; 123 flag[last[i]]:=time; 124 tail:=tail mod maxn+1; 125 end; 126 dis[last[i]]:=dis[q[head]]+w[i]; 127 end; 128 i:=next[i]; 129 end; 130 flag[q[head]]:=time-1; 131 head:=head mod maxn+1; 132 end; 133 end; 134 135 begin 136 init; 137 spfa; 138 work; 139 end. View Code?
轉載于:https://www.cnblogs.com/Randolph87/p/3662732.html
總結
以上是生活随笔為你收集整理的1061: [Noi2008]志愿者招募 - BZOJ的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)一个华科研究生导师的肺腑之言
- 下一篇: 给贼用的密码