首页 > 代码库 > [NOI 2006] 最大获利 80分

[NOI 2006] 最大获利 80分

最后两点怎么搞都要30s+,但是我不会什么优化啊…暂时就这样吧。Dinic的时间复杂度是O(N^2*M)

这题和TDL的幼儿园模板是一样的。

这次写网络流给自己计时了,大约是40min左右,后来都跑去倒腾后面两组数据去了…

program profit;type ptype=^node;     node=record            v,w,flow:longint;            next:ptype;     end;const maxn=55000+10;      inf=maxlongint div 2;var head:array[1..maxn] of ptype;    visit:array[1..maxn] of boolean;    d,q:array[1..maxn] of longint;    n,m,i,j,sta,tar,v,a,b,c,cn:longint;procedure insert(st,ed,r:longint);var p,q,pre:ptype;begin  new(p);  p^.v:=ed;p^.w:=r;p^.flow:=0;p^.next:=nil;  q:=head[st];  if q=nil then head[st]:=p  else    begin      while q^.next<>nil do q:=q^.next;      q^.next:=p;    end;end;function min(a,b:longint):longint;begin  if a<b then exit(a) else exit(b);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;d[star]:=1;visit[sta]:=true;  while star<=rear do    begin      x:=q[star];      y:=head[x];      while y<>nil do        begin          if (not visit[y^.v]) 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;procedure decflow(st,ed,delta:longint);var y:ptype;begin  y:=head[st];  while y^.v<>ed do y:=y^.next;  dec(y^.flow,delta);end;function addflow(p,maxflow:longint):longint;var y:ptype;    o:longint;begin  if (p=tar) or (maxflow=0) then exit(maxflow);  addflow:=0;  y:=head[p];  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;begin  assign(input,profit9.in);reset(input);  assign(output,profit9.out);rewrite(output);  readln(n,m);  sta:=0;tar:=m+n+1;  for i:=1 to n do    begin      read(v);      insert(m+i,tar,v);      insert(tar,m+i,0);    end;  readln;  for i:=1 to m do    begin      readln(a,b,c);      insert(i,m+a,inf);insert(m+a,i,0);      insert(i,m+b,inf);insert(m+b,i,0);      insert(sta,i,c);insert(i,sta,0);      cn:=cn+c;    end;  writeln(cn-network);  close(input);close(output);end.
profit

后来写了个优化是我之前自己发明的decflow,现在我在每条边加了一个域op,指向反向边。速度没有什么提升=w=

program profit2;type ptype=^node;     node=record            v,w,flow:longint;            next,op:ptype;     end;const maxn=55000+10;      inf=maxlongint div 2;var head:array[1..maxn] of ptype;    visit:array[1..maxn] of boolean;    d,q:array[1..maxn] of longint;    n,m,i,j,sta,tar,v,a,b,c,cn:longint;procedure insert(st,ed,r1,r2:longint);var p,q,pre,loc1,loc2:ptype;begin  new(p);  p^.v:=ed;p^.w:=r1;p^.flow:=0;p^.next:=nil;  q:=head[st];  if q=nil then head[st]:=p  else    begin      while q^.next<>nil do q:=q^.next;      q^.next:=p;    end;  loc1:=p;  new(p);  p^.v:=st;p^.w:=r2;p^.flow:=0;p^.next:=nil;  q:=head[ed];  if q=nil then head[ed]:=p  else    begin      while q^.next<>nil do q:=q^.next;      q^.next:=p;    end;  loc2:=p;  loc1^.op:=loc2;  loc2^.op:=loc1;end;function min(a,b:longint):longint;begin  if a<b then exit(a) else exit(b);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;d[star]:=1;visit[sta]:=true;  while star<=rear do    begin      x:=q[star];      y:=head[x];      while y<>nil do        begin          if (not visit[y^.v]) 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 y:ptype;    o:longint;begin  if (p=tar) or (maxflow=0) then exit(maxflow);  addflow:=0;  y:=head[p];  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);              dec(y^.op^.flow,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;begin  assign(input,profit10.in);reset(input);  assign(output,profit10.out);rewrite(output);  readln(n,m);  sta:=0;tar:=m+n+1;  for i:=1 to n do    begin      read(v);      insert(m+i,tar,v,0);      //insert(tar,m+i,0);    end;  readln;  for i:=1 to m do    begin      readln(a,b,c);      insert(i,m+a,inf,0);//insert(m+a,i,0);      insert(i,m+b,inf,0);//insert(m+b,i,0);      insert(sta,i,c,0);//insert(i,sta,0);      cn:=cn+c;    end;  writeln(cn-network);  close(input);close(output);end.
profit2