博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

链表SPFA——LINK 转载于“ 唯思有杰”的博客

Posted on 2010-11-04 21:21  深处的心扉  阅读(307)  评论(0)    收藏  举报

1 type point=^rec;
2 rec=record
3 next:point;
4 endv:integer;
5 w:longint;
6 end;
7  var head,adj:array[1..20000]of point;
8 p,null:point;
9 n:integer;e:longint;start,over:integer;
10 open,closed:longint;
11 q:array[0..1000000]of integer;
12 flag:array[1..20000]of boolean;
13 dist:array[1..20000]of longint;
14
15  procedure init;
16 var i,stv,edv:integer;
17 wei:longint;
18 begin
19 fillchar(q,sizeof(q),0);
20 fillchar(flag,sizeof(flag),false);
21 fillchar(dist,sizeof(dist),127);
22 readln(n,e);
23 for i:=1 to n do
24 begin
25 new(p);
26 head[i]:=p;
27 adj[i]:=p;
28 end;
29 for i:=1 to e do
30 begin
31 readln(stv,edv,wei);
32 adj[stv]^.endv:=edv;
33 adj[stv]^.w:=wei;
34 new(p);
35 adj[stv]^.next:=p;
36 adj[stv]:=p;
37 /////symmetry/////
38 adj[edv]^.endv:=stv;
39 adj[edv]^.w:=wei;
40 new(p);
41 adj[edv]^.next:=p;
42 adj[edv]:=p
43 end;
44 for i:=1 to n do
45 adj[i]^.next:=null;
46 start:=1;over:=n;
47 end;
48
49 procedure spfa(s:longint);
50 var dady:integer;
51 begin
52 flag[s]:=true;q[1]:=s;dist[s]:=0;
53 open:=1;closed:=1;
54 while open<=closed do
55 begin
56 dady:=q[open];
57 p:=head[dady];
58 while (p<>nil) do
59 begin
60 if dist[p^.endv] > dist[dady]+p^.w
61 then begin
62 dist[p^.endv] := dist[dady]+p^.w;
63 if not flag[p^.endv]
64 then begin
65 inc(closed);
66 q[closed]:=p^.endv;
67 flag[p^.endv]:=true;
68 end;
69 end;
70 p:=p^.next;
71 end;
72
73 flag[dady]:=false;
74 inc(open);
75 end;
76 end;
77
78
79 begin
80 init;
81 null:=nil;
82 spfa(start);
83 writeln(dist[over]);
84 readln;readln;
85 end.

优化版的spfa_link

 

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

 

 

 

 

type point=^rec;
     rec=record
          next:point;
          endv:integer;
          w:longint;
          end;
var head,adj:array[1..20000]of point;
    p,null:point;
    n:integer;e:longint;start,over:integer;
    open,closed:longint;
    q:array[0..1000000]of integer;
    flag:array[1..20000]of boolean;
    dist:array[1..20000]of longint;

procedure init;
var i,stv,edv:integer;
    wei:longint;
begin
fillchar(q,sizeof(q),0);
fillchar(flag,sizeof(flag),false);
fillchar(dist,sizeof(dist),127);
readln(n,e);
for i:=1 to n do
  begin
  new(p);
  head[i]:=p;
  adj[i]:=p;
  end;
for i:=1 to e do
  begin
  readln(stv,edv,wei);
  adj[stv]^.endv:=edv;
  adj[stv]^.w:=wei;
  new(p);
  adj[stv]^.next:=p;
  adj[stv]:=p;
  /////symmetry/////
  adj[edv]^.endv:=stv;
  adj[edv]^.w:=wei;
  new(p);
  adj[edv]^.next:=p;
  adj[edv]:=p
  end;
for i:=1 to n do
  adj[i]^.next:=null;
start:=1;over:=n;
end;

procedure spfa(s:longint);
var dady:integer;
begin
flag[s]:=true;q[1]:=s;dist[s]:=0;
open:=1;closed:=1;
while open<=closed do
  begin
  dady:=q[open];
  p:=head[dady];
  while (p<>nil) do
     begin
     if dist[p^.endv] > dist[dady]+p^.w
     then begin
          dist[p^.endv] := dist[dady]+p^.w;
          if not flag[p^.endv]
          then begin
               inc(closed);
               q[closed]:=p^.endv;
               flag[p^.endv]:=true;
               end;
          end;
     p:=p^.next;
     end;

  flag[dady]:=false;
  inc(open);
  end;
end;


begin
init;
null:=nil;
spfa(start);
writeln(dist[over]);
readln;readln;
end.  

1 type point=^rec;
2 rec=record
3 next:point;
4 endv:integer;
5 w:longint;
6 end;
7 var head,adj:array[1..20000]of point;
8 p,null:point;
9 n:integer;e:longint;start,over:integer;
10 open,closed:longint;
11 q:array[0..1000000]of integer;
12 flag:array[1..20000]of boolean;
13 dist:array[1..20000]of longint;
14
15 procedure init;
16 var i,stv,edv:integer;
17 wei:longint;
18 begin
19 fillchar(q,sizeof(q),0);
20 fillchar(flag,sizeof(flag),false);
21 fillchar(dist,sizeof(dist),127);
22 readln(n,e);
23 for i:=1 to n do
24 begin
25 new(p);
26 head[i]:=p;
27 adj[i]:=p;
28 end;
29 for i:=1 to e do
30 begin
31 readln(stv,edv,wei);
32 adj[stv]^.endv:=edv;
33 adj[stv]^.w:=wei;
34 new(p);
35 adj[stv]^.next:=p;
36 adj[stv]:=p;
37 /////symmetry/////
38 adj[edv]^.endv:=stv;
39 adj[edv]^.w:=wei;
40 new(p);
41 adj[edv]^.next:=p;
42 adj[edv]:=p
43 end;
44 for i:=1 to n do
45 adj[i]^.next:=null;
46 start:=1;over:=n;
47 end;
48
49 procedure spfa(s:longint);
50 var dady:integer;
51 begin
52 flag[s]:=true;q[1]:=s;dist[s]:=0;
53 open:=1;closed:=1;
54 while open<=closed do
55 begin
56 dady:=q[open];
57 p:=head[dady];
58 while (p<>nil) do
59 begin
60 if dist[p^.endv] > dist[dady]+p^.w
61 then begin
62 dist[p^.endv] := dist[dady]+p^.w;
63 if not flag[p^.endv]
64 then begin
65 inc(closed);
66 q[closed]:=p^.endv;
67 flag[p^.endv]:=true;
68 end;
69 end;
70 p:=p^.next;
71 end;
72
73 flag[dady]:=false;
74 inc(open);
75 end;
76 end;
77
78
79 begin
80 init;
81 null:=nil;
82 spfa(start);
83 writeln(dist[over]);
84 readln;readln;
85 end.