SPFA算法O(kE)
主要思想是:
    初始时将起点加入队列。每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队。直到队列为空时算法结束。
    这个算法,简单的说就是队列优化的bellman-ford,利用了每个点不会更新次数太多的特点发明的此算法。
SPFA 在形式上和广度优先搜索非常类似,不同的是广度优先搜索中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是说一个点修改过其它的点之后,过了一段时间可能会获得更短的路径,于是再次用来修改其它的点,这样反复进行下去。
算法时间复杂度:O(kE)E是边数。K是常数,平均值为2

算法实现:
    dis[i]记录从起点si的最短路径,w[i][j]记录连接ij的边的长度。pre[v]记录前趋。
    team[1..n]为队列,头指针head,尾指针tail
    布尔数组exist[1..n]记录一个点是否现在存在在队列中。
    初始化:d[s]=0,d[v]=∞(vs),memset(exist,false,sizeof(exist));
    起点入队team[1]=s; head=0; tail=1;exist[s]=true;
    do
    {1、头指针向下移一位,取出指向的点u
    2、exist[u]=false;已被取出了队列
    3、foru相连的所有点v  //注意不要去枚举所有点,用数组模拟邻接表存储
       if (d[v]>d[u]+w[u][v])
         {   d[v]=d[u]+w[u][v];
             pre[v]=u;
             if (!exist[v]) //队列中不存在v点,v入队。
               {         //尾指针下移一位,v入队;
                    exist[v]=true;
                 }
          }
    }
    while (head < tail);
循环队列:
  采用循环队列能够降低队列大小,队列长度只需开到2*n+5即可。例题中的参考程序使用了循环队列。
 
 #include<iostream>
#include<cstdio>
#define N 2010
#include<cstring>
using namespace std;
int dis[N]; //起点到其他点的最短路径
int pre[N]; //前驱
int map[N][N]; //两点之间距离
int ans[N]; //输出
int team[N]; //队列
bool pd[N]; //判断是否在队列中
int head,tail,n,m,from,to;
void work(int a)
{
team[tail++]=a;
pre[a]=a;
dis[a]=;
pd[a]=;
while(head<tail)
{
int d=team[head]; //取出队首元素
for(int i=;i<=n;++i)
if(map[d][i]!=&&dis[i]>dis[d]+map[d][i])
{
dis[i]=dis[d]+map[d][i];
pre[i]=d;
if(!pd[i])
{
team[++tail]=i;
pd[i]=;
}
}
head++;
pd[d]=;
}
printf("%d\n",dis[to]);
}
void print(int a,int b)
{
ans[]=to;
int top=;
int t=b;
while(t!=from)
{
t=pre[t];
ans[++top]=t;
}
for(int i=top;i>=;--i)
printf("%d->",ans[i]);
printf("%d",ans[]);
}
int main()
{
memset(dis,0x7f,sizeof(dis)); //初始化
cin>>n>>m;
for(int i=;i<=m;++i)
{
int x,y,q;
scanf("%d%d%d",&x,&y,&q);
map[x][y]=q; //有向图
}
cin>>from>>to; //需要计算的两点
work(from);
print(from,to);
return ;
}

图论-最短路径--3、SPFA算法O(kE)的更多相关文章

  1. SPFA算法O(kE)

    SPFA算法O(kE) Dijkstra和Floyed是不断的试点.Dijkstra试最优点,Floyed试所有点. Bellman-Ford和SPFA是不断的试边.Bellman-Ford是盲目的试 ...

  2. 【最短路径】 SPFA算法

    上一期介绍到了SPFA算法,只是一笔带过,这一期让我们详细的介绍一下SPFA. 1 SPFA原理介绍 SPFA算法和dijkstra算法特别像,总感觉自己讲的不行,同学说我的博客很辣鸡,推荐一个视频讲 ...

  3. SPFA算法 O(kE)

    主要思想是:     初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束.     这个算法,简单的说就是队列优化 ...

  4. 图论-最短路径 2.Dijkstra算法O (N2)

    2.Dijkstra算法O (N2) 用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法.也就是说,只能计算起点只有一个的情况. Dijkstra的时间复杂度是O (N2),它不能处 ...

  5. 【最短路径】 SPFA算法优化

    首先先明确一个问题,SPFA是什么?(不会看什么看,一边学去,传送门),SPFA是bellman-ford的队列优化版本,只有在国内才流行SPFA这个名字,大多数人就只知道SPFA就是一个顶尖的高效算 ...

  6. 【uva 658】It's not a Bug, it's a Feature!(图论--Dijkstra或spfa算法+二进制表示+类“隐式图搜索”)

    题意:有N个潜在的bug和m个补丁,每个补丁用长为N的字符串表示.首先输入bug数目以及补丁数目.然后就是对M个补丁的描述,共有M行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,第 ...

  7. 【最短路径】 常用算法图解+1376:信使(msner)六解

    进入图之后,最短路径可谓就是一大重点,最短路径的求法有很多种,每种算法各有各的好处,你会几种呢?下面来逐个讲解. 1 floyed算法 1)明确思想及功效:在图中求最短路还是要分开说的,分别是单源最短 ...

  8. 图论最短路径算法总结(Bellman-Ford + SPFA + DAGSP + Dijkstra + Floyd-Warshall)

    这里感谢百度文库,百度百科,维基百科,还有算法导论的作者以及他的小伙伴们...... 最短路是现实生活中很常见的一个问题,之前练习了很多BFS的题目,BFS可以暴力解决很多最短路的问题,但是他有一定的 ...

  9. 最短路径问题的Dijkstra和SPFA算法总结

    Dijkstra算法: 解决带非负权重图的单元最短路径问题.时间复杂度为O(V*V+E) 算法精髓:维持一组节点集合S,从源节点到该集合中的点的最短路径已被找到,算法重复从剩余的节点集V-S中选择最短 ...

随机推荐

  1. 14. Android框架和工具之 ImageLoader(图片加载)

    1. 这个图片加载框架网友很多都已经使用过,而且分析也很到位,这里我就不写了,直接引用别人,尊重别人的劳动成果. 2. 参考如下: (1)Android 开源框架Universal-Image-Loa ...

  2. 程序人生:02我来告诉你,一个草根程序员如何进入BAT

    本文摘自左潇龙博客,原文出处:http://www.cnblogs.com/zuoxiaolong/p/life54.html 引言 首先声明,不要再问LZ谁是林萧,林萧就是某著名程序员小说的主角名字 ...

  3. java反射机制执行命令

    public class Encryptor{ public static void main(String[] args) throws IOException, ClassNotFoundExce ...

  4. hdu_1009 贪心

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. Owin+ASP.NET Identity浅析系列(二)扩展用户属性

    在今天,读书有时是件“麻烦”事.它需要你付出时间,付出精力,还要付出一份心境.--仅以<Owin+ASP.NET Identity浅析系列>来祭奠那逝去的…… 上一篇博客讲了用户登录注册问 ...

  6. (转)进程process和线程thread的关系

    写的很好很明白cpu每次只能执行一个进程,所以其他进程会挂起 在一个进程中,允许存在n个线程,n个线程共享这个进程中的资源 多个线程在共享的时候存在资源互斥,一次只能一个线程,会需要加锁 一次存在固定 ...

  7. Bayesian Theorem

  8. 03_Docker入门(上)之容器创建、容器使用、容器删除

    运维架构服务docker:docker入门 一.确保docker就绪 查看docker程序是否存在,功能是否正常 Docker可执行程序的info命令,该命令会返回所有容器和镜像的数量.Docker使 ...

  9. win 10 如何关闭自动更新

    1.右键“此电脑”图标,点击“管理”,打开“计算机管理”窗口; 2.在“计算机管理”窗口中找到“服务和应用程序”,点击“服务”,打开“服务”窗口; 3.在“服务”中找到“Windows Update” ...

  10. mysql5.7 安装版 表不能输入汉字解决方案

    安装版本 的安装目录没有 my.ini 配置文件 在所在表执行 alter table 数据表名 CONVERT TO CHARACTER SET utf8;