SPFA — shotest path faster algorithm,是一个效率很高的求最短路径的算法,也可以说是bellman-ford算法的优化版。

具体做法是先把起点放入一个队列中。每次取出队顶元素,并pop,看跟该点相邻的其他点是否能够松弛,如果可以松弛,改变数值,如果该点不在队列中,则把能该点push到队列中,直到队列为空。

为了速度更快,可以用邻接表来存储,这样,找与起点相邻的点的速度就会很快!

若要判负环路,则记录一个点的入队次数,若超过边数,则有负权环。

自己用SPFA+静态邻接表写的hdu_2544:可以用作模板

#include <iostream> #include <queue> using namespace std; const long lmax = 1000000000; const long edge_maxn = 10005; //边的最大上限 const long point_maxn = 105; //点的最大上限 struct node {/*node存储边,一个edge代表一条边*/ int v; //终点位置 int w; //权值 int next; //同一起点的下一条边存储在edge数组中的位置(理解了这个静态邻接表就可以了) }edge[edge_maxn]; int pre[point_maxn]; //以该点为起点的第一条边存储在edge数组中的位置 int n; //点的数量 int m; //边的数量 queue<int> Q; int dirs[point_maxn]; bool vis[point_maxn]; void Init() { memset(pre,-1,sizeof(pre)); int Index = 1; int i,j,flag; int x,y,w; for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&w); for(flag=0,j=pre[x];j!=-1;j=edge[j].next) {//重边的情况 if(y == edge[j].v) { if(w < edge[j].w) edge[j].w = w; flag = 1; break; } } if(flag == 1) continue; edge[Index].v = y; edge[Index].w = w; edge[Index].next = pre[x]; //保存x起点的上一条边在edge数组中的位置 pre[x] = Index++; //位置更新 swap(x,y); edge[Index].v = y; edge[Index].w = w; edge[Index].next = pre[x]; pre[x] = Index++; } } void print(int end) { printf("%d/n",dirs[end]); } void SPFA() { int start = 1; int end = n; while(!Q.empty()) { Q.pop(); } memset(vis,0,sizeof(vis)); fill(dirs,dirs+point_maxn,lmax); dirs[start] = 0; vis[start] = 1; Q.push(start); while(!Q.empty()) { int top = Q.front(); //边的起点 Q.pop(); vis[top] = 0; for(int j=pre[top];j!=-1;j=edge[j].next) { int e = edge[j].v; //边的终点 if(dirs[e] > edge[j].w + dirs[top]) { dirs[e] = edge[j].w + dirs[top]; if(!vis[e]) { Q.push(e); vis[e] = 1; } } } } print(end); } int main() { while(scanf("%d%d",&n,&m)!=EOF && (n!=0 || m!=0)) { Init(); SPFA(); } //system("pause"); return 0; }

SPFA + 静态邻接表 模板相关推荐

  1. 最短路径Dijkstra(静态邻接表+优先队列模板)+ 记忆化搜索

    这道题的解题步骤是这样的: (1)用Dijkstra求出每个点到house(也就是2号点)的最短距离,我是记录在数组dist[]中: (2)我们要求的是office(1号点)到house(或2--&g ...

  2. #1093 : 最短路径·三:SPFA算法(邻接表)

    #1093 : 最短路径·三:SPFA算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋! 鬼屋中一共 ...

  3. 有向图,无向图的邻接矩阵和邻接表模板

    图 图的定义 有向图 概念 模板 邻接矩阵 邻接表 无向图 概念 模板 邻接矩阵 邻接表 简单图 完全图 图的定义 图 GGG 由顶点集 VVV 和边集 EEE 组成,记为 G=(V,E)G=(V,E ...

  4. 迪杰斯特拉最全详解(朴素版,堆优化+邻接表存图/链式前向星存图)

    迪杰斯特拉 迪杰斯特拉算法分析 迪杰斯特拉(朴素版) 迪杰斯特拉堆优化(邻接表存图) 迪杰斯特拉堆优化(链式前向星存图) 最短路--spfa(链式前向星存图) 迪杰斯特拉算法分析 一般用三种数据结构存 ...

  5. 【邻接表】77 邻接表:顶点u的下一个邻接点

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  6. 【邻接表】75 邻接表:删除边

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  7. 邻接表:求指定顶点的(出)度

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  8. 邻接表:有权图获取边的权值

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

  9. 邻接表:两个顶点是否相邻

    问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT). 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT.(由于该环境目前仅支持单文件的编译,故将所 ...

最新文章

  1. 使用tab键分割的文章能快速转换成表格。( )_无需按空格键,就能将Word文字对齐,3种方法了解一下...
  2. 【计算机网络】网络层 : IP 数据报格式 ( IP 数据报首部格式 )
  3. Java锁之可重入锁介绍
  4. 【微信开发】-- 发送模板消息
  5. 漫画:996 的本质是什么?
  6. as 运算符 与 where T : class
  7. 中国高校改名发展史:改了名,我们就是一流大学了
  8. win10桌面null图标删除
  9. websockets 和 socketio 的比较
  10. w3c离线手册2019
  11. 怎么用计算机直接截图,电脑截图快捷键怎么使用,电脑怎么快捷键截图
  12. 思岚雷达rplidar S1配置调试全纪录
  13. python读取文件夹下所有图片并重命名_python 对文件夹下图片 批量重命名
  14. osm 搭建离线地图_搭建开源地图服务 - 利用OSMGIS和iD
  15. 多图片上传插件webuploader
  16. 计算机考研前沿知识怎么准备,2016考研复试面试前需充足准备9大内容
  17. 组件化之路 - ViewModel一知半解
  18. 安徽马鞍山郑蒲港地图编码
  19. [置顶] 不写周报才是一件很嘻哈的事
  20. Nginx——反向代理 负载均衡(无理论,案例实操)

热门文章

  1. 2021河南卫生副高考试成绩查询,中国卫生人才网 中国卫生人才网:河南卫生资格成绩查询入口2021...
  2. 自定义函数C语言编写x的n次方,c语言求x的n次方的函数是什么
  3. 《量化金融R语言初级教程》一2.4 切线组合和资本市场线
  4. Mac款origin来了!还不来看看!
  5. CSS处理文字一行显示,超出用省略号。包含一个微信小程序使用css文字溢出一行显示的一个bug
  6. 1.1 Java ME
  7. Elasticsearch+Kibana集群部署(3节点)
  8. ViSP学习笔记(十五):关键点跟踪
  9. 四川大学计算机综合实践报告,四川大学计算机操作系统第四实验报告
  10. 怎么更改wifi频段_【wifi信号频率】wifi频率怎么设置 wifi2.4g和5g哪个更好