首页 > 代码库 > [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.
后来写了个优化是我之前自己发明的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.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。