[HB2014 Week5] Allot 人员分配

这两天决心专门搞好网络流了 - -

题解在什么瞎胡搞跟我说要连n+2和n+1容量为无穷的边…我看了下std才做的…

坑死人的地方就是,需要求多次网络流,每次别忘了把流给清空了…这次是用链表所以专门写了一个clearflow过程,如果是静态链表就可以fillchar了…

program allot2;
type ptype=^node;
     node=record
            v,w,flow:longint;
            next:ptype;
          end;
const maxn=400+10;
      inf=maxlongint;
var m,n,k,i,j,x,y,l,mid,r,sta,tar:longint;
    head:array[1..maxn] of ptype;
    q,d:array[1..maxn] of longint;
    visit:array[1..maxn] of boolean;
function min(a,b:longint):longint;
begin
  if a>b then exit(b) else exit(a);
end;

procedure insert(st,ed,r:longint);
var p,q,pre:ptype;
begin
  //if (st=n+1) or (st=n+2) then r:=inf;
  //if (ed=n+1) or (ed=n+2) then r:=0;
  new(p);new(q);
  p^.v:=ed;p^.w:=r;p^.flow:=0;p^.next:=nil;
  q:=head[st];
  if q=nil then
    begin
      new(head[st]);
      head[st]^:=p^;
    end
  else
    begin
      while q<>nil do
        begin
          pre:=q;q:=q^.next;
        end;
      new(q);
      q^:=p^;
      pre^.next:=q;
    end;
end;

procedure decflow(st,ed,delta:longint);
var x,y:ptype;
begin
  y:=head[st];
  while y^.v<>ed do y:=y^.next;
  y^.flow:=y^.flow-delta;
end;

function bfs:boolean;
var star,rear,x:longint;
    y:ptype;
begin
  fillchar(visit,sizeof(visit),false);
  fillchar(q,sizeof(q),0);
  fillchar(d,sizeof(d),0);
  star:=1;rear:=1;q[star]:=sta;visit[sta]:=true;d[star]:=1;
  while star<=rear do
    begin
      x:=q[star];
      y:=head[x];
      while y<>nil do
        begin
          if (visit[y^.v]=false) and (y^.w>y^.flow) then
            begin
              inc(rear);
              q[rear]:=y^.v;
              visit[y^.v]:=true;
              d[y^.v]:=d[x]+1;
            end;
          y:=y^.next;
        end;
      inc(star);
    end;
  bfs:=visit[tar];
end;

function addflow(p,maxflow:longint):longint;
var x,y:ptype;
    o:longint;
begin
  if (p=tar) or (maxflow=0) then exit(maxflow);
  y:=head[p];addflow:=0;
  while y<>nil do
    begin
      if (d[y^.v]=d[p]+1) and (y^.w>y^.flow) then
        begin
          o:=addflow(y^.v,min(maxflow,y^.w-y^.flow));
          if o>0 then
            begin
              inc(y^.flow,o);
              decflow(y^.v,p,o);
              inc(addflow,o);
              dec(maxflow,o);
              if maxflow=0 then break; //!
            end;
        end;
      y:=y^.next;
    end;
end;

function network:longint;
begin
  network:=0;
  while bfs do
    inc(network,addflow(sta,inf));
end;

procedure clearflow;  //!
var i,j:longint;
    y:ptype;
begin
  for i:=1 to n+3 do
    begin
      y:=head[i];
      while y<>nil do
        begin
          y^.flow:=0;
          y:=y^.next;;
        end;
    end;
end;

begin
  assign(input,'allot9.in');reset(input);
  assign(output,'allot9.out');rewrite(output);
  readln(n,m,k);
  //build_graph;
  for i:=1 to m do
    begin
      readln(x,y,l,mid,r);
      insert(y,x,mid-l);
      insert(x,y,r-mid);
    end;
  insert(n+3,n+2,inf);insert(n+2,n+3,0);
  insert(n+3,n+1,inf);insert(n+1,n+3,0);
  //main
  sta:=n+3;
  for i:=1 to n do
    begin
      clearflow;
      tar:=i;
      if network>=k then writeln('1') else writeln('0');
    end;
end.
allot

自己写网络流的时候忘记了if maxflow=0 then exit这句了,虽然不影响结果但是会影响速度。

自己电脑上跑有点慢,又不知道哪儿的OJ有…Sigh…

原文地址:https://www.cnblogs.com/Sky-Grey/p/3839961.html