bzoj 2424: [HAOI2010]订货 (费用流)

直接费用流,天数就是点数

 

 
type
  arr=record
    toward,next,cap,cost:longint;
  end;
const
  maxm=200000;
  maxn=200;
  mm=1<<30;
var
  edge:array[0..maxm]of arr;
  first,slack,d:array[0..maxn]of longint;
  chose:array[0..maxn]of boolean;
  n,maxflow,maxcost,s,t,tot,esum: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;
 
function aug(x,flow:longint):longint;
var
  now,more,i,too,value:longint;
begin
  if x=t then begin
    inc(maxflow,flow);
    inc(maxcost,flow*d[s]);
    exit(flow);
  end;
  chose[x]:=true;
  i:=first[x];
  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 d[x]=d[too]+value then begin
        more:=aug(too,min(flow-now,edge[i].cap));
        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],d[too]+value-d[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>=mm then exit(false);
  for i:=1 to tot do
    if chose[i] then inc(d[i],spent);
  exit(true);
end;
 
procedure into;
var
  i,j,k,m,sum:longint;
begin
  esum:=-1;
  fillchar(first,sizeof(first),255);
  readln(n,m,sum);
  tot:=n+2;
  s:=tot-1;
  t:=tot;
  for i:=1 to n do begin
    read(j);
    addedge(i,t,j,0);
  end;
  for i:=1 to n do begin
    read(j);
    addedge(s,i,maxlongint,j);
  end;
  for i:=1 to n-1 do
    addedge(i,i+1,sum,m);
end;
 
begin
  into;
  fillchar(d,sizeof(d),0);
  maxflow:=0;
  maxcost:=0;
  repeat
    fillchar(slack,sizeof(slack),$7f);
    repeat
      fillchar(chose,sizeof(chose),false);
    until aug(s,maxlongint)<=0;
  until not rel;
  writeln(maxcost);
  readln;
  readln;
end.
View Code

 

posted @ 2015-03-22 22:07  Macaulish  阅读(326)  评论(0编辑  收藏  举报