SPFA
来源:互联网 发布:大话数据库 pdf 下载 编辑:程序博客网 时间:2024/06/03 21:05
SPFA是类似bfs的一种图论方法,运用队列更新dis[i],求得图中1~n的最短路径。
SPFA中用到dis[i]表示图中每一点距离起点的长度,bz[i]用来记录编号为i的点是否入队,a[x,y]表示图中x~y之间的距离,b[x,i]表示编号为x的点的第i条边的终点,每次更新这个终点到起点的距离,以当前入队的点来更新,最后求出答案。
ps:这种方法有空间限制,因为有二维数组。
代码:
var dis,f:array[0..100000]of longint; a,b:array[0..1000,0..1000]of longint; bz:array[1..1000]of boolean; i,j,head,tail,k,n,m,x,y,z,t:longint;begin readln(n,m); for i:=1 to m do begin readln(x,y,z); inc(b[x,0]);//记录编号为x的点有多少条边 b[x,b[x,0]]:=y; if (a[x,y]>z)or(a[x,y]=0) then a[x,y]:=z; end; head:=0; tail:=1; for i:=1 to n do if dis[i]=0 then dis[i]:=maxlongint; dis[1]:=0; bz[1]:=true; f[1]:=1; repeat inc(head); k:=f[head]; for i:=1 to b[k,0] do begin if a[k,b[k,i]]+dis[k]<dis[b[k,i]] then//更新 begin dis[b[k,i]]:=a[k,b[k,i]]+dis[k]; if bz[b[k,i]]=false then//判断是否入过队 begin inc(tail); f[tail]:=b[k,i]; bz[b[k,i]]:=true; end; end; end; bz[k]:=false; until head>=tail; for i:=2 to n do begin if dis[i]=maxlongint then writeln(-1) else writeln(dis[i]); end;end.
既然这种方法不行那么我们有就可以用数组模拟这个过程,
tov[i]表示编号为i的边的终点;
next[i]表示编号为i的边下一个要搜索的边;
last[i]表示以i为节点开始的最后一条边;
len[i]表示编号为i的权值;
那么程序改成这样:
var f,dis,next,last,len,tov:array[1..100000]of longint; bz:array[1..100000]of boolean; head,tail,n,m,i,x,y,z,tot,daan:longint;procedure insert(x,y,z:longint);//插入过程begin inc(tot); tov[tot]:=y; len[tot]:=z; next[tot]:=last[x]; last[x]:=tot;end;procedure spfa;var x,y,i:longint;begin f[1]:=1; bz[1]:=true; head:=0; tail:=1; for i:=1 to n do dis[i]:=maxlongint div 2; dis[1]:=0; while head<>tail do begin head:=head mod n+1; x:=f[head]; i:=last[x]; while (i<>0) do begin y:=tov[i]; if (dis[y]>dis[x]+len[i])then begin dis[y]:=dis[x]+len[i]; if (not bz[y])then begin tail:=tail mod n+1; f[tail]:=y; bz[y]:=true; end; end; i:=next[i]; end; bz[x]:=false; end;end;begin read(n,m); for i:=1 to m do begin readln(x,y,z); insert(x,y,z);//有向边 end; spfa; for i:=2 to n do begin if(dis[i]=maxlongint div 2)then begin writeln('-1'); end else begin writeln(dis[i]); end; end;end.
1 0
- SPFA
- spfa
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- spfa
- spfa
- SPFA
- SPFA
- oracle中处理XML
- 关于ScrollView中嵌套listview焦点滑动问题 解决
- d盘无法格式化怎么解决
- OpenCV优化:图像的遍历4种方式
- HashTable的双重散列表
- SPFA
- 洛谷 P1984 [SDOI2008]烧水问题
- PAT编程基础 5-18 二分法求多项式单根 (20分)
- Elasticsearch增删改查
- 扫盲 HTTPS 和 SSL/TLS 协议[2]:可靠密钥交换的难点,以及身份认证的必要性
- APP 启动白屏 解决 4.4 onstart 不运行 的问题
- 使用Struts2的输入校验(一)--校验规则文件
- PC端和手机端调转
- UART协议