---恢复内容开始---
SPFA——O(k*E)
Shortest Path Faster Algorithm
•
维护一个队列,里面存放所有需要进行迭代的点。初始时队列
中只有一个起点
S
。用一个布尔数组记录每个点是否处在队列中。
•
每次迭代,取出队头的点
v
,依次枚举从
v
出发的边
v
→
u
,设边
的长度为
len
,判断
Dist[v]+len
是否小于
Dist[u]
,若小于则改进
Dist[u]
,将
Fa[u]
记为
v
,并且由于
S
到
u
的最短距离变小了,有
可能
u
可以改进其它的点,所以若
u
不在队列中,就将它放入队
尾。这样一直迭代下去直到队列变空,也就是
S
到所有的最短距
离都确定下来,结束算法。
【程序】
1 procedure spfa; 2 begin 3 fillchar(q,sizeof(q),0); 4 h:=0; t:=0;//队列 5 fillchar(v,sizeof(v),false);//v[i]判断i是否在队列中 6 for i:=1 to n do 7 dist[i]:=maxint;//初始化最小值 8 inc(t); 9 q[t]:=1; 10 v[1]:=true; 11 dist[1]:=0;//这里把1作为源点 12 while not(h=t) do 13 begin 14 h:=(h+1)mod n; 15 x:=q[h]; 16 v[x]:=false;//出队列 17 for i:=1 to n do 18 if (cost[x,i]>0)and(dist[x]+cost[x,i]<dist[i]) then 19 begin 20 dist[i]:=dist[x]+cost[x,i]; 21 if not(v[i]) then 22 begin 23 t:=(t+1)mod n; 24 q[t]:=i; 25 v[i]:=true 26 end; 27 end; 28 end; 29 end;
•
SPFA
在形式上和宽度优先搜索非常类似,不同
的是宽度优先搜索中一个点出了队列就不可能
重新进入队列,但是
SPFA
中一个点可能在出队
列之后再次被放入队列,也就是一个点改进过
其它的点之后,过了一段时间可能本身会再次
被改进,于是再次用来改进其它的点,这样反
复迭代下去。
---恢复内容结束---