邻接表
利用链式储存结构。对于每一个顶点,开一条链,依次存储以该点为起点的边。
下面的代码用g数组储存边的信息,ls[i]储存i这个顶点对应的链的起始位置。
通时g中的next域使所有起始点为i的边连成一条链。
const
MaxE=100000;
MaxV=50000;
type
rec=record
x,y,w,next:longint;
end;
var
n,m:longint;
g:array [1..MaxE] of rec;
ls:array [1..MaxV] of longint;
procedure main;
var
i:longint;
begin
read(n,m);
for i:=1 to n do ls[i]:=0;
for i:=1 to m do
with g[i] do
begin
read(x,y,w);
next:=ls[x];
ls[x]:=i;
end;
end;
begin
main;
end.
如果我们需要访问以St为起始位置的所有边,可以如下操作:
t:=ls[St];
while t>0 do
begin
with g[t] do
writeln(x,’ ’y,’ ’,w);
t:=g[t].next;
end;
时空复杂度都是O(V+E)
以上复制,啦啦啦!
分析一下上面的程序
让我们画一个表:
输入:
1 2 3
2 4 5
1 3 6
3 5 1
2 5 3
当输入1 2 3时
| 1 | 2 | 3 | 4 | 5 |
x | 1 |
|
|
|
|
y | 2 |
|
|
|
|
w | 3 |
|
|
|
|
next | 0 |
|
|
|
|
| 1 | 2 | 3 | 4 | 5 |
Ls | 1 |
|
|
|
|
当输入2 4 5 时
| 1 | 2 | 3 | 4 | 5 |
x | 1 | 2 |
|
|
|
y | 2 | 4 |
|
|
|
w | 3 | 5 |
|
|
|
next | 0 | 0 |
|
|
|
| 1 | 2 | 3 | 4 | 5 |
Ls | 1 | 2 |
|
|
|
当输入1 3 6 时
| 1 | 2 | 3 | 4 | 5 |
x | 1 | 2 | 1 |
|
|
y | 2 | 4 | 3 |
|
|
w | 3 | 5 | 6 |
|
|
next | 0 | 0 | 1 |
|
|
| 1 | 2 | 3 | 4 | 5 |
Ls | 3 | 2 |
|
|
|
当输入3 5 1 时
| 1 | 2 | 3 | 4 | 5 |
x | 1 | 2 | 1 | 3 |
|
y | 2 | 4 | 3 | 5 |
|
w | 3 | 5 | 6 | 1 |
|
next | 0 | 0 | 1 | 0 |
|
| 1 | 2 | 3 | 4 | 5 |
Ls | 3 | 2 | 4 |
|
|
当输入2 5 3 时
| 1 | 2 | 3 | 4 | 5 |
x | 1 | 2 | 1 | 3 | 2 |
y | 2 | 4 | 3 | 5 | 5 |
w | 3 | 5 | 6 | 1 | 3 |
next | 0 | 0 | 1 | 0 | 2 |
| 1 | 2 | 3 | 4 | 5 |
Ls | 3 | 5 | 4 |
|
|
就是这么的简单!!!
当我们把它运用到spfa中时,spfa的速度就会变得快!!!
程序如下:
const
maxe=100000;
maxv=2000000;
type
arr=record
x,y,w,next:longint;
end;
var
n,m,s,q:longint;
ls:array[1..maxe] of longint;
a:array[1..maxv] of arr;
f:array[1..maxe] of longint;
v:array[1..maxe] of longint;
d:array[1..maxe] of longint;
i,j,k:longint;
ans:longint;
procedure spfa;
var
i,j,k:longint;
head,tail:longint;
begin
fillchar(f,sizeof(f),$7f);
head:=0;
tail:=1;
v[s]:=1;
d[1]:=s;
f[s]:=1;
repeat
head:=head mod maxe+1;
j:=ls[d[head]];
while j<>0 do
begin
with a[j] do
begin
if f[x]+w<f[y]
then
begin
f[y]:=f[x]+w;
if v[y]=0
then
begin
tail:=tail modmaxe+1;
d[tail]:=y;
v[y]:=1;
end;
end;
j:=next;
end;
end;
v[d[head]]:=0;
until head=tail;
end;
当然,这个东西还有很多用处,如搜索什么的。