spfa 链表(优化版)

 
  
 
    
优化版的spfa_link



program spfa; { By Zine.Chant }
type link = ^node;
node
= record
x,y:longint;
{ x是指向的节点,y是边权 }
next:link;
end ;
var i,n,m,x,y,z,start,head,tail:longint;
f:
array [ 1 .. 10000 ] of longint; { 当前最优值 }
a:
array [ 1 .. 10000 ] of link; { 每个点连出的边的链表的头 }
d:
array [ 1 .. 1000000 ] of longint; { 队列 }
o:
array [ 1 .. 10000 ] of boolean; { 检验元素是否在未被处理的队列中 }
r:link;
procedure setup;
begin
assign(input,
' spfa.in ' );
assign(output,
' spfa.out ' );
reset(input);
rewrite(output);
end ;
procedure endit;
begin
close(input);
close(output);
end ;

begin
setup;
readln(n,m);
{ 点和边的个数 }
readln(start);
{ 起点 }
for i: = 1 to n do
begin
new(a[i]);
fillchar(a[i]^,sizeof(a[i]^),
0 ); { 要有初始化的好习惯 }
end ;
for i: = 1 to m do
begin
readln(x,y,z);
new(r);
r^.x:
= y;
r^.y:
= z;
r^.next:
= a[x]^.next;
a[x]^.next:
= r;
new(r);
r^.x:
= x;
r^.y:
= z;
r^.next:
= a[y]^.next;
a[y]^.next:
= r;
end ; { 读入边 }
head:
= 0 ;
tail:
= 1 ;
d[
1 ]: = start;
for i: = 1 to n do
f[i]:
= maxlongint;
f[start]:
= 0 ;
fillchar(o,sizeof(o),false);
while head < tail do
begin
inc(head);
o[d[head]]:
= false; { 这三处是spfa的核心优化 }
r:
= a[d[head]];
while r^.next <> nil do
begin
r:
= r^.next;
if f[d[head]] + r^.y < f[r^.x] then
begin
f[r^.x]:
= f[d[head]] + r^.y;
if o[r^.x] then continue; { 这三处是spfa的核心优化 }
inc(tail);
d[tail]:
= r^.x;
o[d[tail]]:
= true; { 这三处是spfa的核心优化 }
end ;
end ;
end ;
for i: = 1 to n do
writeln(i:
5 , ' : ' ,f[i]: 8 ); { 输出起点到每一个点的最短路径 }
endit;
end .

 

优化版的spfa_link
 
   
优化版的spfa_link



program spfa; { By Zine.Chant }
type link = ^node;
node
= record
x,y:longint;
{ x是指向的节点,y是边权 }
next:link;
end ;
var i,n,m,x,y,z,start,head,tail:longint;
f:
array [ 1 .. 10000 ] of longint; { 当前最优值 }
a:
array [ 1 .. 10000 ] of link; { 每个点连出的边的链表的头 }
d:
array [ 1 .. 1000000 ] of longint; { 队列 }
o:
array [ 1 .. 10000 ] of boolean; { 检验元素是否在未被处理的队列中 }
r:link;
procedure setup;
begin
assign(input,
' spfa.in ' );
assign(output,
' spfa.out ' );
reset(input);
rewrite(output);
end ;
procedure endit;
begin
close(input);
close(output);
end ;
begin
setup;
readln(n,m);
{ 点和边的个数 }
readln(start);
{ 起点 }
for i: = 1 to n do
begin
new(a[i]);
fillchar(a[i]^,sizeof(a[i]^),
0 ); { 要有初始化的好习惯 }
end ;
for i: = 1 to m do
begin
readln(x,y,z);
new(r);
r^.x:
= y;
r^.y:
= z;
r^.next:
= a[x]^.next;
a[x]^.next:
= r;
new(r);
r^.x:
= x;
r^.y:
= z;
r^.next:
= a[y]^.next;
a[y]^.next:
= r;
end ; { 读入边 }
head:
= 0 ;
tail:
= 1 ;
d[
1 ]: = start;
for i: = 1 to n do
f[i]:
= maxlongint;
f[start]:
= 0 ;
fillchar(o,sizeof(o),false);
while head < tail do
begin
inc(head);
o[d[head]]:
= false; { 这三处是spfa的核心优化 }
r:
= a[d[head]];
while r^.next <> nil do
begin
r:
= r^.next;
if f[d[head]] + r^.y < f[r^.x] then
begin
f[r^.x]:
= f[d[head]] + r^.y;
if o[r^.x] then continue; { 这三处是spfa的核心优化 }
inc(tail);
d[tail]:
= r^.x;
o[d[tail]]:
= true; { 这三处是spfa的核心优化 }
end ;
end ;
end ;
for i: = 1 to n do
writeln(i:
5 , ' : ' ,f[i]: 8 ); { 输出起点到每一个点的最短路径 }
endit;
end .

 


2
3
4
5 program spfa;{By Zine.Chant}
6 type link=^node;
7 node=record
8 x,y:longint;{x是指向的节点,y是边权}
9 next:link;
10 end;
11 var i,n,m,x,y,z,start,head,tail:longint;
12 f:array[1..10000] of longint;{当前最优值}
13 a:array[1..10000] of link; {每个点连出的边的链表的头}
14 d:array[1..1000000] of longint; {队列}
15 o:array[1..10000] of boolean;{检验元素是否在未被处理的队列中}
16 r:link;
17 procedure setup;
18 begin
19 assign(input,'spfa.in');
20 assign(output,'spfa.out');
21 reset(input);
22 rewrite(output);
23 end;
24 procedure endit;
25 begin
26 close(input);
27 close(output);
28 end;
29 begin
30 setup;
31 readln(n,m);{点和边的个数}
32 readln(start);{起点}
33 for i:=1 to n do
34 begin
35 new(a[i]);
36 fillchar(a[i]^,sizeof(a[i]^),0);{要有初始化的好习惯}
37 end;
38 for i:=1 to m do
39 begin
40 readln(x,y,z);
41 new(r);
42 r^.x:=y;
43 r^.y:=z;
44 r^.next:=a[x]^.next;
45 a[x]^.next:=r;
46 new(r);
47 r^.x:=x;
48 r^.y:=z;
49 r^.next:=a[y]^.next;
50 a[y]^.next:=r;
51 end; {读入边}
52 head:=0;
53 tail:=1;
54 d[1]:=start;
55 for i:=1 to n do
56 f[i]:=maxlongint;
57 f[start]:=0;
58 fillchar(o,sizeof(o),false);
59 while head<tail do
60 begin
61 inc(head);
62 o[d[head]]:=false; {这三处是spfa的核心优化}
63 r:=a[d[head]];
64 while r^.next<>nil do
65 begin
66 r:=r^.next;
67 if f[d[head]]+r^.y<f[r^.x] then
68 begin
69 f[r^.x]:=f[d[head]]+r^.y;
70 if o[r^.x] then continue; {这三处是spfa的核心优化}
71 inc(tail);
72 d[tail]:=r^.x;
73 o[d[tail]]:=true; {这三处是spfa的核心优化}
74 end;
75 end;
76 end;
77 for i:=1 to n do
78 writeln(i:5,':',f[i]:8); {输出起点到每一个点的最短路径}
79 endit;
80 end.

转载于:https://www.cnblogs.com/lj_cherish/archive/2010/11/16/1878508.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值