一、基于各种数据结构的SPFA

以下各个数据均为不卡SPFA的最短路模板:P3371 【模板】单源最短路径(弱化版)的测试时间

1、STL队列:用时: 1106ms / 内存: 8496KB

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001];
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));queue<int>q;q.push(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.front();q.pop();vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){q.push(y);vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

2、STL栈:用时: 4257ms / 内存: 8536KB(#2,#9,#10TLE)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001];
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));stack<int>q;q.push(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.top();q.pop();vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){q.push(y);vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

3、模拟栈:用时: 4242ms / 内存: 8508KB(#2,#9,#10TLE)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001],stk[500001],top;
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));top=1;stk[top]=s;vis[s]=1;dist[s]=0;while(top>0){int t=stk[top];top--;vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){stk[++top]=y;vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

4、STL优先队列:用时: 1377ms / 内存: 8612KB

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001],stk[500001],top;
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));priority_queue<int>q;q.push(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.top();q.pop();vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){q.push(y);vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

时间总的来说是这个样子的:STL栈>模拟栈>STL优先队列>STL队列

二、SPFA的优化

SPFA目前常见的优化有3种,分别是:SLF优化,LLL优化,随机优化。

1、SLF优化:

SLF优化采取的策略是开一个双端队列,如果即将入队节点大于队首值就插入前端,否则插入后端。是最常见的也是最好用的SPFA优化方法

用时: 1100ms / 内存: 8512KB

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001],sum;
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));deque<int>q;q.push_back(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.front();q.pop_front();vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){if(dist[y]<=dist[q.front()])q.push_front(y);else q.push_back(y);vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

2、LLL优化:

LLL优化也是开一个双端队列,每次去队首看是否大于平均值,大于就插入队尾继续寻找。看起来高大上实际应用不多的SPFA优化

用时: 1114ms / 内存: 8500KB

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001],sum;
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));deque<int>q;q.push_back(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.front();if(dist[t]*q.size()>sum){q.pop_front();q.push_back(t);continue;}q.pop_front();sum-=dist[t];vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){q.push_back(y);sum+=dist[y];vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{read();spfa(s);pr();return 0;
}

  

3、随机优化:

随机优化就是rand一下,为0插入队首,为1插入队尾,最不靠谱的优化。

用时: 1259ms / 内存: 8516KB

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<queue>
#include<algorithm>
#define inf 336860180
using namespace std;
int n,m,s,x,y,z,v[500001],w[500001],head[500001],nxt[500001],cnt,maxx,dist[500001],sum;
bool vis[500001];
void add(int a,int b,int c)
{v[++cnt]=b;w[cnt]=c;nxt[cnt]=head[a];head[a]=cnt;
}
void read()
{cin>>n>>m>>s;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);}
}
void spfa(int s)
{memset(dist,20,sizeof(dist));deque<int>q;q.push_back(s);vis[s]=1;dist[s]=0;while(!q.empty()){int t=q.front();q.pop_front();vis[t]=0;for(int i=head[t];i;i=nxt[i]){int y=v[i];if(dist[y]>dist[t]+w[i]){dist[y]=dist[t]+w[i];if(!vis[y]){if(rand()%2)q.push_front(y);else q.push_back(y);vis[y]=1;}}}}
}
void pr()
{for(int i=1;i<=n;i++){if(dist[i]!=inf)cout<<dist[i];else cout<<"2147483647";cout<<" ";}
}
int main()
{srand(time(NULL));read();spfa(s);pr();return 0;
}

  

优化后的时间排序:RAND>LLL>朴素>SLF

如果你喜欢我的文章就来个点赞收藏转发关注吧!!!

转载于:https://www.cnblogs.com/szmssf/p/11047202.html

基于各种基础数据结构的SPFA和各种优化相关推荐

  1. python structure_GitHub - CYZYZG/Data_Structure_with_Python: 这是我在学习《基于Python的数据结构》的时候的笔记与代码...

    Data_Structure_with_Python 这是我在学习<基于Python的数据结构>的时候的笔记与代码 主要参考:数据结构与算法(Python) 对于算法的时间效率,我们可以用 ...

  2. OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co

    OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...

  3. 一个基于运气的数据结构,你猜是啥?

    作者 | why技术  责编 | 张文 头图 | CSDN 下载自东方 IC 来源 | why技术(ID:hello_hi_why) 从排行榜切入 懂行的老哥一看这个小标题,就知道我要以排行榜作为切入 ...

  4. 基础数据结构和算法概念

    本文涉及更多的是概念,代码部分请参考之前写过的 2 篇博客 排序算法 基于Javascript 基本数据结构和查找算法 本文主要是基础的数据结构和算法概念,可能部分地方会涉及更高级的算法和算法,具体内 ...

  5. redis源码剖析(7):基础数据结构quicklist

    目录 1.quicklist概述 2.quicklist源码分析 2.1 定义 2.2 push操作 2.3 节点压缩 3.总结 1.quicklist概述    quicklist是一个3.2版本之 ...

  6. redis源码剖析(3):基础数据结构dict

    目录 1.dict概述 2.字典的定义 3.哈希算法 4.字典的初始化及新增键值对 4.1 字典初始化 4.2 新增键值对 5.rehash(重新散列)操作 5.1 rehash操作方式 5.2 re ...

  7. Redis--五种基础数据结构及应用场景

    Redis 有 5 种基础数据结构,分别为:string (字符串).list (列表).set (集合).hash (哈希) 和 zset (有序集合). 一. string (字符串) 字符串 s ...

  8. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

  9. 基于C++的数据结构-1

    介绍基于C++的数据结构-参考书目[数据结构.算法与应用(C++语言描述)–赵宏(主编)] [基本概念准备] 信息: 对现实世界中事物的存在方式或运动状态的反映,在计算机中以数据的形式存储. 数据: ...

最新文章

  1. 黑色诱惑 -- Media Player 11
  2. 网络推广期间遇到页面无效收录情况网络推广专员如何应对?
  3. java读写锁降级_java的读写锁中锁降级的问题
  4. gbk文件转为utf8文件
  5. python获得命令行参数的方法
  6. 牛客网_PAT乙级_1016程序运行时间(15)
  7. java中number类型能否相除_Java中 如果复数类成员是int型,怎么实现两个复数相除...
  8. 一元线性回归决定系数_回归分析|笔记整理(1)——引入,一元线性回归(上)...
  9. 基于springboot框架的java学生管理系统
  10. Python3安装核心价值观包报错
  11. 雷电游戏java源代码,java雷电游戏源码项目
  12. su命令的隐患——用户提权
  13. Pareto相关理论
  14. 计算机键盘输入法基础知识,3、使用键盘打字 --电脑基础知识
  15. 南京湖南路学计算机哪家好,在南京只知道夫子庙湖南路你就OUT了!真正的美食街在此!!...
  16. 【C语言】定义一个函数,求长方体的体积
  17. 2021-05-13 python样条插值(一)
  18. js实现获取当前时间是本月第几周和年的第几周的方法
  19. python中的random模块_Python内置random模块生成随机数的方法
  20. 2008年上半年系统分析师上午英语试题分析与参考答案

热门文章

  1. Java并发编程:Lock和Synchronized 转
  2. 应用程序正常初始化(0xc0000135)失败的解决方法
  3. 大批量插入数据如何优化
  4. Add-in Express for Office and .NET v7.3支持VS 2013预览
  5. NFC能否成为“标配”?
  6. 安装完成Fedora 15 LXDE 定制版后的操作
  7. 我感觉ae比较难用,就是做这种画中画的视频,final cut pro真香
  8. rhel5.5安装vsftpd并配置虚拟用户及开放防火墙和selinux
  9. 蓝桥杯九宫重排(bfs+用set去重)
  10. 从零学前端第十四讲:AngularJs进阶-作用域和控制器