邻接表的spfa

邻接表

利用链式储存结构。对于每一个顶点,开一条链,依次存储以该点为起点的边。

下面的代码用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;

 

当然,这个东西还有很多用处,如搜索什么的。

转载于:https://www.cnblogs.com/a-loud-name/p/6184837.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值