图论-SPFA

复习笔记-SPFA求单源最短路

一本通上的SPFA用的是邻接矩阵,而前向星的SPFA更为常用,所以作为巩固复习和改进,我写了这篇随笔。

SPFA的基本操作

基本原理

动态逼近法。

实现思路

设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。——度娘

那么松弛操作是个啥玩意儿呢?

如果IK + KJ < IJ

那么IJ = IK + KJ

也就是说,如果经过一个中转点到达终点比当前记录的两点最短路还要近,那么就把这个长度更新为两点最短路。

伪代码

 1 SPFA(X){
 2     初始化:d[x][i]赋值为INF; d[x][x]=0;
 3     x入队;  更新visit;
 4     while(队里有元素){
 5         k = 队首; 队首出队; 
 6         while(i = 遍历以k为起点的所有边){
 7             取出 j = i;
 8             if(XK + KJ < XJ){
 9                 XJ = XK + KJ;
10                 if(j不在队里,也就是!visit[j]){
11                     j入队;
12                     更新visit; 
13                 }
14             }
15         } 
16     } 
17 }

程序实现

基本程序

如果d[x][y]存储x到y的路长,断路存为INF,visit来表示一个点在不在队列内,那么我们可以这样实现SPFA

 1 void spfa(int x){
 2     d[x][x] = 0;
 3     queue <int> nod; nod.push(x); visit[x] = 1;
 4     while(nod.size()){
 5         int k = nod.front(); nod.pop(); visit[k] = 0;
 6         for(int j = 1; j <= n; j++){
 7             if(d[x][j] > d[x][k] + d[k][j]){
 8                 d[x][j] = d[x][k] + d[k][j];
 9                 if(!visit[j]){
10                     nod.push(j);
11                     visit[j]=1;
12                 }
13             }
14         }
15     }
16 }

 

与链式前向星的结合

很明显上面的程序是针对用邻接矩阵存图的方式,那么如果我们使用链式前向星(如果不知道的话看这里

用d[i]存储x到i的最短路长,初始化赋值为INF,d[x]赋值为0,visit[i]记录i是否在队列,那么程序是这样的(to为终点v为边权next为下一条边,head[i]为i为起点的第一条边)

 1 void spfa(int x){
 2     fill(d + 1, d + n + 1, INF); d[x] = 0;
 3     queue <int> nod; nod.push(x); visit[x] = 1;
 4     while(nod.size()){
 5         int k = nod.front(); nod.pop(); visit[k] = 0;
 6         for(int i = head[k]; i != 0; i = edge[i].next){
 7             int j = edge[i].to;
 8             if(d[j] > d[k] + edge[i].w){
 9                 d[j] = d[k] + edge[i].w;
10                 if(!visit[j]){
11                     nod.push(j);
12                     visit[j]=1;
13                 }
14             }
15         }
16     }
17 }

这样就可以求出来x到每个点的最短路长了嘤。

板子题

LGOJ-P1339

LGOJ-P2384

LGOJ-P2299

LGOJ-P1359

posted @ 2018-11-16 13:35 Noire02 阅读(...) 评论(...) 编辑 收藏
Live2D