1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| program bzoj_2879; var l:array[1..3200000]of record st,ed,pre,f,c:longint; end; pp:array[0..40]of longint; n,m,p,i,j,ans,tot,ss,tt:longint; t:array[1..40,1..100]of longint; lst,d,from:array[0..81000]of longint; function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; procedure link(a,b,f,c:longint); begin inc(tot); l[tot].pre:=lst[a]; lst[a]:=tot; l[tot].st:=a; l[tot].ed:=b; l[tot].f:=f; l[tot].c:=c; end; procedure insert(a,b,f,c:longint); begin link(a,b,f,c); link(b,a,0,-c); end; function spfa:boolean; const qs=81000; var q:array[1..qs]of longint; v:array[0..qs]of boolean; hd,tl,now,k:longint; begin hd:=0; tl:=1; q[1]:=ss; fillchar(v,sizeof(v),false); fillchar(d,sizeof(d),$7f); v[ss]:=true; d[ss]:=0; while hd<>tl do begin inc(hd); if hd>qs then hd:=1; now:=q[hd]; k:=lst[now]; while k<>0 do begin if (l[k].f>0)and(d[now]+l[k].c<d[l[k].ed]) then begin d[l[k].ed]:=d[now]+l[k].c; from[l[k].ed]:=k; if not v[l[k].ed] then begin v[l[k].ed]:=true; inc(tl); if tl>qs then tl:=1; q[tl]:=l[k].ed; end; end; k:=l[k].pre; end; v[now]:=false; end; if d[tt]>maxlongint>>1 then exit(false); exit(true); end; procedure flow; var x,f,c,pos,cnt:longint; begin x:=from[tt]; f:=maxlongint; while x<>0 do begin f:=min(f,l[x].f); if l[x].st=ss then pos:=l[x].ed; x:=from[l[x].st]; end; x:=from[tt]; while x<>0 do begin inc(ans,f*l[x].c); dec(l[x].f,f); inc(l[x xor 1].f,f); x:=from[l[x].st]; end; c:=(pos-1)mod m+1; cnt:=(pos-1) div m+1; for x:=1 to n do insert(cnt*m+c,m*p+x,1,t[x,c]*(cnt+1)); end; begin readln(n,m); p:=0; for i:=1 to n do begin read(pp[i]); inc(p,pp[i]); end; for i:=1 to n do for j:=1 to m do read(t[i,j]); ss:=0; tt:=m*p+n+1; tot:=1; for i:=1 to p do for j:=1 to m do insert(ss,(i-1)*m+j,1,0); for i:=1 to n do insert(m*p+i,tt,pp[i],0); for i:=1 to m do for j:=1 to n do insert(i,m*p+j,1,t[j,i]); ans:=0; while spfa do flow; writeln(ans); end.
|