一、基于各种数据结构的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[],w[],head[],nxt[],cnt,maxx,dist[];
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
queue<int>q;
q.push(s);
vis[s]=;
dist[s]=;
while(!q.empty())
{
int t=q.front();
q.pop();
vis[t]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

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[],w[],head[],nxt[],cnt,maxx,dist[];
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
stack<int>q;
q.push(s);
vis[s]=;
dist[s]=;
while(!q.empty())
{
int t=q.top();
q.pop();
vis[t]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

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[],w[],head[],nxt[],cnt,maxx,dist[],stk[],top;
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
top=;
stk[top]=s;
vis[s]=;
dist[s]=;
while(top>)
{
int t=stk[top];
top--;
vis[t]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

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[],w[],head[],nxt[],cnt,maxx,dist[],stk[],top;
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
priority_queue<int>q;
q.push(s);
vis[s]=;
dist[s]=;
while(!q.empty())
{
int t=q.top();
q.pop();
vis[t]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

时间总的来说是这个样子的: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[],w[],head[],nxt[],cnt,maxx,dist[],sum;
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
deque<int>q;
q.push_back(s);
vis[s]=;
dist[s]=;
while(!q.empty())
{
int t=q.front();
q.pop_front();
vis[t]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

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[],w[],head[],nxt[],cnt,maxx,dist[],sum;
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
deque<int>q;
q.push_back(s);
vis[s]=;
dist[s]=;
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]=;
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]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
read();
spfa(s);
pr();
return ;
}

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[],w[],head[],nxt[],cnt,maxx,dist[],sum;
bool vis[];
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=;i<=m;i++)
{
cin>>x>>y>>z;
add(x,y,z);
}
}
void spfa(int s)
{
memset(dist,,sizeof(dist));
deque<int>q;
q.push_back(s);
vis[s]=;
dist[s]=;
while(!q.empty())
{
int t=q.front();
q.pop_front();
vis[t]=;
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()%)q.push_front(y);
else q.push_back(y);
vis[y]=;
}
}
}
}
}
void pr()
{
for(int i=;i<=n;i++)
{
if(dist[i]!=inf)cout<<dist[i];
else cout<<"";
cout<<" ";
}
}
int main()
{
srand(time(NULL));
read();
spfa(s);
pr();
return ;
}

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

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

基于各种基础数据结构的SPFA和各种优化的更多相关文章

  1. Vlc基础数据结构记录

    1.  Vlc基础数据结构 hongxianzhao@hotmail.com 1.1  基础数据结构 struct vlc_object_t,相关文件为src\misc\objects.c. 定义为: ...

  2. Flink内存管理源代码解读之基础数据结构

    概述 在分布式实时计算领域,怎样让框架/引擎足够高效地在内存中存取.处理海量数据是一个非常棘手的问题.在应对这一问题上Flink无疑是做得非常杰出的,Flink的自主内存管理设计或许比它自身的知名度更 ...

  3. redis 基础数据结构实现

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

  4. redis基础数据结构及编码方式

    redis基础数据结构和编码方式 一.基础数据结构 1)简单动态字符串 2)双端链表 3)字典 4)跳跃表 5)整数集合 6)压缩列表 二.对象类型与编码 在redis的数据库中创建一个新的键值对时, ...

  5. Redis基础——剖析基础数据结构及其用法

    这是一个系列的文章,打算把Redis的基础数据结构.高级数据结构.持久化的方式以及高可用的方式都讲一遍,公众号会比其他的平台提前更新,感兴趣的可以提前关注,「SH的全栈笔记」,下面开始正文. 如果你是 ...

  6. 基于php基础语言编写的小程序之计算器

    基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...

  7. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  8. 理解 OpenStack + Ceph (4):Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  9. hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)

    基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...

随机推荐

  1. java 中的引用类型

    GC基本原理 GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征 ...

  2. STS插件创建springboot项目,pom第一行报unkown错误

    Description    Resource    Path    Location    TypeUnknown    pom.xml    /amq-provider    line 1     ...

  3. windows 如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中

    题目]如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中 一.概述 之前安装tensorflow的安装了anaconda并用它进行安装,anaconda ...

  4. hdu4417 Super Mario (树状数组/分块/主席树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个长度为n的序列,有m个询问,每次询问包含l,r,h,即询问区间[l,r]小于等 ...

  5. 【LGR-062】洛谷10月月赛 III div.2 (A-C)

    前言 100+100+46+0=246pts 300多名 以后每次比赛都要有进步哦!qwq 小D与笔试 水题 Code #include<algorithm> #include<io ...

  6. k8s 1.9.0-手动安装-2

    1 下载etcd新版 https://github.com/coreos/etcd/releases 直接下载k8s的二进制包 https://github.com/kubernetes/kubern ...

  7. man arch

    ARCH(1)   Linux Programmer?. Manual/Linux程序员手册       ARCH(1) NAME/名称       arch - print machine arch ...

  8. Prometheus + Node Exporter + Grafana 监控主机运行信息

      上一篇文章中讲了如何利用Prometheus和Grafana监控SpringBoot应用的JVM信息,这次就来看看如何监控 服务器运行状态,先列出用到的工具: Prometheus node_ex ...

  9. ht-1 jdk calendar类

    package calendardemo; import java.util.Calendar; public class CalendarDemo { /** * @param args */ pu ...

  10. php array_splice()函数 语法

    php array_splice()函数 语法 作用:从数组中移除选定的元素,并用新元素取代它.dd马达价格 语法:array_splice(array,start,length,array) 参数: ...