bzoj 1877: [SDOI2009]晨跑 (网络流)

明显拆点费用流;

 

 
type
  arr=record
    toward,next,cap,cost:longint;
  end;
 
const
  mm=1<<30;
  maxn=1000;
  maxm=300000;
 
var
  edge:array[0..maxm]of arr;
  first,slack,d:array[0..maxn]of longint;
  chose:array[0..maxn]of boolean;
  s,t,n,m,tot,esum,maxflow,maxcost: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;
  now:=0;
  chose[x]:=true;
  i:=first[x];
  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(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],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,l:longint;
begin
  esum:=-1;
  fillchar(first,sizeof(first),255);
  readln(n,m);
  s:=1;
  t:=n<<1;
  tot:=t;
  for i:=2 to n-1 do
    addedge(i<<1-1,i<<1,1,0);
  addedge(1,2,maxlongint,0);
  addedge(n<<1-1,n<<1,maxlongint,0);
  for i:=1 to m do begin
    readln(j,k,l);
    addedge(j<<1,k<<1-1,1,l);
  end;
  fillchar(d,sizeof(d),0);
end;
 
begin
  into;
  maxcost:=0;
  maxflow:=0;
  repeat
    fillchar(slack,sizeof(slack),$7f);
    repeat
      fillchar(chose,sizeof(chose),false);
    until  aug(s,maxlongint)<=0;
  until not rel;
  writeln(maxflow,' ',maxcost);
end.
View Code

 

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