POJ 2135 费用流 spfa

来源:互联网 发布:淘宝上怎么换货啊 编辑:程序博客网 时间:2024/05/18 03:26

本人蒟蒻啊!!!!!!!!!!!!!!

本周停课想把网络流和平衡树的算法都掌握的,可惜太弱了,只把网络流弄会。


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  begind[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别人初中就会了,我现在还不会,太垃圾了啊啊啊啊)

原创粉丝点击