有关概念:

  最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径

  SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径)

  约定:图中不存在负权环,用邻接表存储有向图,di存放从起点到结点i的最短路,q为队列,保存待处理节点

思路:

  首先指定起点入队,取当前队头结点u,沿每一条与u相连的边向外扩展,对该边所指向的结点v松弛(比较当前dv与当前du加此边长,更新最短路值dv,以及最短路径prev)如果v不在队列中且更新了最短路值,v进队,直至队列中没有元素时终止

  较于Dijkstra,SPFA能处理带负权的边,但如果点进队的次数过多,时间效率就不如前者高

 #include<cstdio>
#include<cstring>
#define MAXN
#define MAXM
#define INF 214748364
int n,m,cnt,d[MAXN],heads[MAXN],q[MAXN],pre[MAXN];
int head,tail;//队头、队尾指针
bool viss[MAXN];//结点i是否在队列中
struct node
{
int u,v;
int next;
int val;
}edge[MAXM];
void add(int x,int y,int z)
{
edge[++cnt].u=x;
edge[cnt].v=y;
edge[cnt].next=heads[x];
edge[cnt].val=z;
heads[x]=cnt;
}
void SPFA()
{
head=;tail=;
q[]=;
viss[]=;//默认1为起点
while(head<tail)
{
for(int i=heads[q[head]];i!=;i=edge[i].next)
{
if(d[q[head]]+edge[i].val<d[edge[i].v])
{
d[edge[i].v]=d[q[head]]+edge[i].val;//松弛
pre[edge[i].v]=i;//记录最短路径,pre存储边的序号
if(!viss[edge[i].v])//如果v不在队列中,入队
{
q[tail++]=edge[i].v;
viss[edge[i].v]=true;
}
}
}
viss[q[head]]=false;
head++;//队头出队
}
}
void print(int x)
{
if(edge[x].u==)
{
printf("%d %d ",,edge[x].v);
return ;
}
print(pre[edge[x].u]);
printf("%d ",edge[x].v);
}
int main()
{
scanf("%d%d",&n,&m);
memset(heads,,sizeof(heads));
for(int i=;i<=n;i++)d[i]=INF;
int x,y,z;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);//默认输入双向边,所以存储两条方向相反的边
}
SPFA();
printf("%d\n",d[n]);
x=pre[n];
print(x);//输出路径
return ;
}

*参考:http://baike.baidu.com/link?url=FxZ5Ces0YdAHMPmVyJG7f_wJ9-8c6EHreyuDEfHpXsldfk-rfj7ZjtSETKX5Jp14WW28sutbf5zcnLSBcmKzM9zaUVD1Sn9WCwsidDVUhPnSX__1ukG38VjR5g5-5NvK_fjovt-kZIJ1bC4HK1MaBa

图论-单源最短路-SPFA算法的更多相关文章

  1. 单源最短路——SPFA算法(Bellman-Ford算法队列优化)

    spfa的算法思想(动态逼近法):     设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路 ...

  2. 单源最短路SPFA算法

    $huaji^{233……}$模板:洛谷 P3371 #include<iostream> #include<algorithm> #include<cstdio> ...

  3. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  4. 单源最短路——Bellman-Ford算法

    1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...

  5. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  6. 单源最短路 Bellman-Ford算法(有向图)

    // 单源最短路问题 // Bellman-Ford算法 // 复杂度O(V*E) //! 可以判断负圈 #include <cstdio> #include <iostream&g ...

  7. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  8. 单源最短路Dijkstra算法——matlab实现

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  9. 单源最短路(Dijkstra算法)

    #返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...

随机推荐

  1. Django 2.0 学习(05):Django Admin

    Django Admin 站点的管理者,而非访问者. 创建admin用户 首先,执行下面命令: python manage.py createsuperuser 其次,输入用户名和密码: Userna ...

  2. BZOJ4011 HNOI2015落忆枫音(动态规划+拓扑排序)

    DAG中每个点选一条入边就可以构成一棵有向树,所以如果没有环答案就是∏degreei. 考虑去掉含环的答案.可以看做把环缩点,剩下的点仍然可以任意选入边.于是去除的方案数即为∏degreei/∏deg ...

  3. Python虚拟环境virtualenv的使用

    virtualenv 是一个创建孤立的Python环境的工具.可以让你创建各自独立的.互不影响的Python开发环境. 使用pip安装即可 pip install virtualenv 查看是否安装成 ...

  4. POJ1236:Network of Schools——题解

    http://poj.org/problem?id=1236 首先还是缩点,然后入度为0的点的个数就是你要投文件个数. 然后我们对于入度和出度为0的点的个数取最大值即为答案. (简单证明:入度和出度为 ...

  5. BZOJ4552:[HEOI2016/TJOI2016]排序——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://www.luogu.org/problemnew/show/P2824 在2 ...

  6. 洛谷 P2860 [USACO06JAN]冗余路径Redundant Paths 解题报告

    P2860 [USACO06JAN]冗余路径Redundant Paths 题目描述 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们 ...

  7. 去掉vue 中的代码规范检测(Eslint验证)

    去掉vue 中的代码规范检测(Eslint验证): 1.在搭建vue脚手架时提示是否启用eslint检测的. Use ESLint to lint your code? 写 no; 2.如果项目已经生 ...

  8. 使用javaScript和JQuery制作经典面试题:光棒效果

    使用javaScript与jQuery添加CSS样式的区别和步骤 使用javaScript制作光棒效果 --首先是javaScript <script> $(function () { v ...

  9. Promise用法总结

    1. Promise的状态   Promise对象有三个状态: 1. 进行中(pending) 2. 成功(resolved) 3. 失败(rejected)   2. 生成一个Promise对象   ...

  10. bzoj2083: [Poi2010]Intelligence test(二分+vector)

    只是记录一下vector的用法 v.push_back(x)加入x v.pop_back()弹出最后一个元素 v[x]=v.back(),v.pop_back()删除x,但是会打乱vector顺序 v ...