前向星 - SPFA

2020-04-17 00:29

在我们切题的时候经常会遇到一个问题...图很大,边很少.很显然这样用矩阵存图就很不值得了!而且很可能会因为这个而是你的程序爆掉。遇到这个问题大部分的OIer们都会去用链表来存数据...但是,作为沙茶的我..并不喜欢用链表....于是...我们就可以用前向星~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

首先我们来看,普通的矩阵存图存的是map[i,j] [即i到j的权值].如果..有100000个点的话...就悲剧了..这样就是100000*100000

然后,前向星是保存边,一共申请三个数组:a[i] b[i] e[i] 他们分别表示:第i条边的起点编号,第i条边的终点编号,第i条边的权值。 于是我们就可以这样读数据: -------------------------------- readln(n,m); for i:=1 to m do readln(a[i],b[i],e[i]);

---------------------------------

然后就qsort(a,1,m),为的是让这些起始编号有序(让终止编号有序也可以,看个人喜好了...不过一般都是排起始编号).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这就是前向星了.其实也是非常的简单.空间复杂度视边的个数(也就是m)而定.

我们可以来看一道题:

-------------------------------------------------------------------------------------------------------------------- Aim Netbar

(netbar.pas/c/cpp) 【问题背景】

绵阳中学以人数众多而闻名。三个年级共有10000 多人,学生多了附近的网吧也多。

Mzoiers 都热衷于Dota,可学校的机子配置相当差(评测服务器除外),根本不能玩

Dota,那就只有去网吧。星期天到星期五都是晚上 10:20 才下晚自习,几乎没时间玩。

然而星期六下午放假是绝好的时间,但是学校人多啊,一放学去网吧的人就开始狂奔,竞争

之激烈,抢到机子的难度非常之大。往往在我们到达网吧之前都坐满了。

学校到网吧的路是错综复杂的, 以致于到一个自己想去的网吧都有非常多的路线可以选

择,而路线的长度又不相同,这样就决定了要花费的时间,因此想要尽快到达,选择一条最

佳的线路是很有必要的。 【问题描述】

为了简化问题,我们把学校与周边的网吧看做图中的顶点,学校与网吧,网吧与网吧之

间的路线看做边,每个边都有一个权,表示我们走完这条路的时间,由于放学人流量大,如

果反向走会有危险,因此这是一个有向图。

我的的学校在 S点,想要去的网吧在 T点。你的任务就是选择一条最佳路线,使得从

学校到目的地网吧的时间最短,你只需要输出最短到达时间即可。 【输入文件】

netbar.in 中共有M+2 行数据

第一行两个整数 N,M,表示点数和边数。

然后M行每行3 个正整数(u,v,t),表示有一条可由u 到v耗时为 t的边。 最后一行两个正整数S、T。 【输出文件】

netbar.out 中,只有一行,一个整数表示最短时间。如果 S、T之间不存在通路则输

出“No Solution!”(双引号不输出, “!”为西文标点)。 【输入样例】 44 1 23 2 4 10 1 35 3 45 14

【输出样例】 10

【数据规模】

对于30%的数据保证有 1

--------------------------------------------------------------------------------------------------------------------

这道题很明显就是用SPFA,但是由于这个数据规模,我们只能有两种方法:1.链表 2.前向星

这里链表就不再赘述...我们的主题是前向星.

恩...直接插程序吧....

~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ var

a,b,e:array[1..10000] of longint; vis:array[1..20000] of boolean; q,d,f:array[1..20010] of longint;

n,m,i,s,t:longint;

procedure qsort(l,r:longint); var

i,j,x,y:longint; begin i:=l; j:=r;

x:=a[(l+r) shr 1]; repeat

while a[i]x do dec(j); if not(i>j) then begin y:=a[i]; a[i]:=a[j]; a[j]:=y; y:=b[i]; b[i]:=b[j]; b[j]:=y; y:=e[i]; e[i]:=e[j]; e[j]:=y; inc(i); dec(j); end; until i>j;

if i

procedure spfa(s:longint); var

i,k,l,t:longint; begin

fillchar(vis,sizeof(vis),0);

for i:=1 to n do d[i]:=maxlongint; d[s]:=0; l:=0; t:=1; q[1]:=s; vis[s]:=true; repeat

l:=l mod 10000 +1; k:=q[l];

for i:=f[k] to f[k+1]-1 do if d[k]+e[i]

d[b[i]]:=d[k]+e[i]; if not vis[b[i]] then begin

t:=t mod 10000 +1; q[t]:=b[i];

vis[b[i]]:=true; end; end;

vis[k]:=false; until l=t; end;

procedure init; begin

assign(input,'netbar.in');reset(input);

assign(output,'netbar.out');rewrite(output);

readln(n,m); for i:=1 to m do readln(a[i],b[i],e[i]);

qsort(1,m);

for i:=1 to m do if f[a[i]]=0 then f[a[i]]:=i; f[n+1]:=m+1;

for i:=n downto 1 do if f[i]=0 then f[i]:=f[i+1]; readln(s,t); end;

procedure terminate; begin

close(input); close(output); halt; end;

begin init; spfa(s); writeln(d[t]); terminate; end.

~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-

前向星的用途:一般是用来优化SPFA的。

前向星的缺点:不能用起点直接终点定位,如果程序必须要定位的话,我们也不能示弱,最好不要用朴素的方法来定位,这样很花时间的。最好,就是用二分的思想进行查找(也就是常说的对半查找): {伪代码}

Function binsearch(i,j,x);//在i,j区间中找x. {

if a[(i+j)shr 1]>x then exit(binsearch(i,(i+j))shr 1) else exit(binsearch((i+j)shr 1 +1,j)); }

一种数据结构,以储存边的方式来存储图。 构造方法如下: 读入每条边的信息 将边存放在数组中

把数组中的边按照起点顺序排序 前向星就构造完了

通常用在点的数目太多,或两点之间有多条弧的时候。 一般在别的数据结构不能使用的时候才考虑用前向星。 除了不能直接用起点终点定位以外,前向星几乎是完美的。

--------------------------------------------------------------------------------------------------------- 最基本的前项星优化的spfa(有向图),复杂度O(ke). var

a,b,e:array[1..1000] of longint; vis:array[1..2000] of boolean; q,d,f:array[1..2001] of longint; n,m,i,s,t:longint;

procedure qsort(l,r:longint); var i,j,x,y:longint; begin i:=l; j:=r;

x:=a[(l+r) shr 1]; repeat

while a[i]


前向星 - SPFA.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:常用有机酸结构、化学式、分子量、别名

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: