bzoj 3280: 小R的烦恼 (网络流)
和开发计划一样(数组开太小wa了好多次,然后为什么这么慢?
type arr=record toward,next,cap,cost:longint; end; const maxm=200000; maxn=300; var edge:array[0..maxm]of arr; dist,first,sch,a,new,old,p,slack:array[0..maxn]of longint; chose:array[0..maxn]of boolean; maxcost,maxflow,n,s,t,tot,esum,i,tt,sum,jj:longint; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; procedure add(i,j,k,l:longint); begin inc(esum); edge[esum].toward:=j; edge[esum].next:=first[i]; first[i]:=esum; edge[esum].cap:=k; edge[esum].cost:=l; end; procedure addedge(i,j,k,l:longint); begin add(i,j,k,l); add(j,i,0,-l); end; procedure into; var n,m1,m2,i,j,k,cost1,time:longint; begin readln(n,m1,m2); fillchar(first,sizeof(first),255); esum:=-1; for i:=1 to m1 do sch[i]:=i; tot:=m1; for i:=1 to n do begin inc(tot); new[i]:=tot; inc(tot); old[i]:=tot; end; inc(tot); s:=tot; inc(tot); t:=tot; for i:=1 to n do begin read(a[i]); inc(sum,a[i]); end; for i:=1 to m1 do begin read(j,p[i]); addedge(s,sch[i],j,0); end; for i:=1 to n do begin addedge(s,old[i],a[i],0); for j:=1 to m1 do addedge(sch[j],new[i],a[i],p[j]); addedge(new[i],t,a[i],0); end; for i:=1 to m2 do begin read(time,cost1); for j:=1 to n-time do for k:=j+time+1 to n do addedge(old[j],new[k],maxlongint,cost1); end; end; function aug(x,flow:longint):longint; var now,more,i,too,value:longint; begin if x=t then begin inc(maxflow,flow); inc(maxcost,dist[s]*flow); exit(flow); end; // writeln(x); i:=first[x]; chose[x]:=true; now:=0; while i>=0 do begin too:=edge[i].toward; value:=edge[i].cost; if (edge[i].cap>0) and (not chose[too]) then if dist[x]=dist[too]+value then begin more:=aug(too,min(edge[i].cap,flow-now)); dec(edge[i].cap,more); inc(edge[i xor 1].cap,more); inc(now,more); if flow=now then exit(flow); end else slack[too]:=min(slack[too],dist[too]+value-dist[x]); i:=edge[i].next; end; exit(now); end; function rel:boolean; var i,spent:longint; begin spent:=maxlongint; for i:=1 to tot do if not chose[i] then spent:=min(spent,slack[i]); if spent=maxlongint then exit(false); for i:=1 to tot do if chose[i] then inc(dist[i],spent); exit(true); end; begin readln(tt); for jj:=1 to tt do begin sum:=0; into; fillchar(dist,sizeof(dist),0); maxcost:=0; maxflow:=0; repeat for i:=1 to tot do slack[i]:=maxlongint; repeat fillchar(chose,sizeof(chose),false); until aug(s,maxlongint)<=0; until not rel; write('Case ',jj,': '); if sum=maxflow then writeln(maxcost) else writeln('impossible'); end; end.
因疲惫而轻易入眠,是对自己一天努力的最好褒奖。 要和泪子一起努力怀抱梦想对抗残酷的现实……