历时四天(本周三至本周六),本人的第一道网络流题目终于通过了…虽然这么慢才搞懂很大程度是因为脑子笨,但是还是要吐槽一下:
(1)选的这道题吧居然是无向图,对于初学者我表示呵呵,昨晚到现在一直在纠结怎么搞。一开始觉得在循环里加个j=0就好了,后来发现运行速度慢以为错了,后来才发现是自作聪明把书上一行代码给去掉了…QAQ
(2)这道题是多汇点,一开始还以为有x个汇点运行x次取最大呢,又脑残了;
(3)我的教材…写的是手动栈,虽然这免除了溢出,但是长度堪忧啊QAQ,而且数据才100根本不会溢出的啊…Anyway有空要把递归写法给写一下,不过手工栈的确很久没有码过了~~
至少这么一折腾,算是差不多懂了一些网络流算法,有空学一下Dinic。还有一周就要考试了,纯属酱油心态的我也要加油啦~
f表示flow也就是存储流,findpath和adjust这两个子段的名字太浅显了不解释了…s是手工栈。
program vijos_p1524; var map,f:array[0..101,0..101] of longint; s,mark:array[-1..101] of integer; n,e,m,a,b,w,x,i,j:integer; ans,anst,top:longint; function findpath:boolean; begin fillchar(mark,sizeof(mark),0); i:=1;j:=0;mark[1]:=1;top:=1;s[top]:=1; repeat i:=abs(s[top]); repeat j:=j+1; if (mark[j]=0) and (map[i,j]<>0) then begin if map[i,j]>f[i,j] then begin inc(top);s[top]:=j; mark[j]:=1; end else if f[j,i]>0 then begin inc(top);s[top]:=-j; mark[j]:=1; end; end; until (j>=n+1) or (i<>abs(s[top])); if i=abs(s[top]) then begin j:=abs(s[top]); mark[abs(s[top])]:=0; s[top]:=0; dec(top); end else j:=0; until (top=0) or (s[top]=x); findpath:=(top>0); end; procedure adjust; var i,j,k,x,z:longint; begin k:=1;i:=s[k];z:=maxlongint; repeat inc(k);j:=s[k]; if j<0 then x:=f[-j,i] else x:=map[i,j]-f[i,j]; if x<z then z:=x; i:=abs(j); until k=top; k:=1;i:=s[k]; repeat inc(k);j:=s[k]; if j<0 then begin f[-j,i]:=f[-j,i]-z; end else begin f[i,j]:=f[i,j]+z; end; i:=abs(j); until k=top; end; procedure work; var j:integer; begin fillchar(f,sizeof(f),0); anst:=0; while findpath do adjust; for j:=1 to n+1 do anst:=anst+f[1,j]; end; begin readln(n,e); for i:=1 to e do begin readln(a,b,w); map[a,b]:=w;map[b,a]:=w; end; readln(m); for i:=1 to m do begin read(x); map[x,n+1]:=maxlongint; end; x:=n+1;{top:=1;s[top]:=1;mark[1]:=1;j:=0;} work; writeln(anst); end.