本人蒟蒻啊!!!!!!!!!!!!!!
本周停课想把网络流和平衡树的算法都掌握的,可惜太弱了,只把网络流弄会。
http://poj.org/problem?id=2135
大概题意:从起点到终点再回到起点 每条边最多走一边。问最少的费用。
这一题算是比较裸的费用流了,类似于某年NOIP的传纸条。
这题可以看成从起点到终点走两次,不过最短路显然是不对的。我们可以建一个超级源点,然后从超级S点向起点建立一条流量为2 费用为0的边,然后其余的边流量为0,
做两次spfa费用流就可以了。(以前背zkw的,然后这次因为余翔等说没有题目刻意卡spfa网络流,再加上spfa很早就会了,没有看标称就自己写出来了,幸福感爆棚啊!)
注意的是,这题是无向图+重边,读入一条边要建立4条边,也就是当作2条有向边建图,我用的是数组模拟邻接表(类似于边集数组(贾教风格?))
code:
var
a,b,c,w,next,an:array[0..50015] of longint;
s,t,tot,n,m,i,x,y,z,ans,cost:longint;
q:array[0..2000000] of longint;
procedure spfa;
var
min,cos,h,e,i,p,x,y,z:longint;
d,pre,path:array[0..5000] of longint;
v:array[0..5000] of boolean;
begin
fillchar(path,sizeof(path),0);
fillchar(pre,sizeof(pre),0);
fillchar(v,sizeof(v),true);
h:=1;e:=1;q[h]:=s;
for i:=0 to t+10 do
d[i]:=maxlongint;
d[s]:=0;v[s]:=false;
pre[s]:=0;path[s]:=0;
while(h<=e) do
begin
x:=q[h];
p:=b[x];
while p<>0 do
begin
y:=a[p];
z:=c[p];
if ((d[x]+z)<d[y]) and (w[p]<>0) then
begin
d[y]:=d[x]+z;
pre[y]:=x;
path[y]:=p;
if v[y] then
begin
e:=e+1;
v[y]:=false;
q[e]:=y;
end;
end;
p:=next[p];
end;
v[x]:=true;
h:=h+1;
end;
i:=t;min:=maxlongint;cos:=0;
if path[i]=0 then exit;
while i<>s do
begin
p:=path[i];
cos:=cos+c[p];
i:=pre[i];
if w[p]<min then min:=w[p];
end;
i:=t;
while i<>s do
begin
p:=path[i];
w[p]:=w[p]-min;
w[an[p]]:=w[an[p]]+min;
i:=pre[i];
end;
ans:=ans+min;
cost:=cost+cos*min;
end;
procedure insert(x,y,z,g,ww:longint);
begin
tot:=tot+1;
next[tot]:=b[x];
b[x]:=tot;
a[tot]:=y;
w[tot]:=ww;
c[tot]:=z;
an[tot]:=tot+g;
end;
begin
tot:=0;
fillchar(b,sizeof(b),0);
read(n,m);
for i:=1 to m do
begin
read(x,y,z);
if (x>n) or (y>n) then halt;
insert(x,y,z,1,1);
insert(y,x,-z,-1,0);
insert(y,x,z,1,1);
insert(x,y,-z,-1,0);
end;
s:=n+1;t:=n;
insert(s,1,0,1,2);
insert(1,s,0,-1,0);
insert(1,s,0,1,2);
insert(s,1,0,-1,0);
ans:=0;
cost:=0;
spfa;
spfa;
writeln(cost);
end.
RP+++++
继续复习复习sap全优化的代码 学习平衡树(TT别人初中就会了,我现在还不会,太垃圾了啊啊啊啊)
本文聚焦于网络流算法的学习与应用,并通过解决POJ平台上的问题来加深理解。同时,作者提及了尝试学习平衡树算法的挑战,表达了对自身技能提升的渴望。
815

被折叠的 条评论
为什么被折叠?



