bzoj 1061 志愿者招募 费用流
详见BYV的博客,写的非常全面https://www.byvoid.com/blog/noi-2008-employee
/************************************************************** Problem: 1061 User: BLADEVIL Language: Pascal Result: Accepted Time:1496 ms Memory:1028 kb ****************************************************************/ //By BLADEVIL var n, m :longint; pre, other, len, cost :array[0..50010] of longint; last :array[0..2010] of longint; l :longint; source, sink :longint; ans :longint; flag :array[0..1020] of boolean; dis, que, father :array[0..1020] of longint; function min(a,b:longint):longint; begin if a>b then min:=b else min:=a; end; procedure connect(a,b,c,d:longint); begin inc(l); pre[l]:=last[a]; last[a]:=l; other[l]:=b; len[l]:=c; cost[l]:=d; end; procedure init; var i :longint; x, y, z :longint; begin read(n,m); source:=n+2; sink:=source+1; x:=0; l:=1; for i:=1 to n do begin read(y); if y-x>0 then begin connect(source,i,y-x,0); connect(i,source,0,0); end else begin connect(i,sink,x-y,0); connect(sink,i,0,0); end; x:=y; end; connect(n+1,sink,x,0); connect(sink,n+1,0,0); for i:=1 to m do begin read(x,y,z); connect(x,y+1,maxlongint div 10,z); connect(y+1,x,0,-z); end; for i:=2 to n+1 do begin connect(i,i-1,maxlongint div 10,0); connect(i-1,i,0,0); end; end; function spfa:boolean; var h, t, cur :longint; q, p :longint; begin filldword(dis,sizeof(dis) div 4,maxlongint div 10); que[1]:=source; dis[source]:=0; h:=0; t:=1; while t<>h do begin h:=h mod 1010+1; cur:=que[h]; flag[cur]:=false; q:=last[cur]; while q<>0 do begin p:=other[q]; if len[q]>0 then if dis[p]>dis[cur]+cost[q] then begin father[p]:=q; dis[p]:=dis[cur]+cost[q]; if not flag[p] then begin t:=t mod 1010+1; que[t]:=p; flag[p]:=true; end; end; q:=pre[q]; end; end; if dis[sink]=maxlongint div 10 then exit(false) else exit(true); end; procedure update; var low, cur :longint; begin cur:=sink; low:=maxlongint; while cur<>source do begin low:=min(low,len[father[cur]]); cur:=other[father[cur] xor 1]; end; cur:=sink; while cur<>source do begin dec(len[father[cur]],low); inc(len[father[cur] xor 1],low); ans:=ans+low*cost[father[cur]]; cur:=other[father[cur] xor 1]; end; end; procedure main; begin while spfa do update; writeln(ans); end; begin init; main; end.