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.
posted @ 2010-11-16 14:28  lj_cherish  阅读(387)  评论(0编辑  收藏  举报