一、基于各种数据结构的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. jQuery学习总结04-文档处理

    1.append(content|fn) 说明:向每个匹配的元素内部追加内容. 这个操作与对指定的元素执行appendChild方法,将它们添加到文档中的情况类似. content(要追加到目标中的内 ...

  2. nodejs 更新代码自动刷新页面

    安装第三方工具: nodemon npm install --global nodemon 安装完毕后使用: 之前使用: node xxx.js 改成 nodemon xxx.js 只要通过nodem ...

  3. 第一次写的MySQLHelper

    一. 第一次写MysqlHelper,用来管理城市的数据库 二.MySQLHelper源代码 using MySql.Data.MySqlClient; using System; using Sys ...

  4. python的list内存分配算法

    前提:python为了提高效率会为list预先分配一定的内存空间供其使用,避免在每次append等操作都去申请内存,下面简单分析下list的内存分配算法,主要就是两段. 1.当没有元素时,newsiz ...

  5. #10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ

    题目:#10042. 「一本通 2.1 练习 8」收集雪花 看到网上没有这道题的题解,所以写一下. 要标记数字是否存在,看到x<=1e9,所以考虑用离散化,然后开一个last数组,last[i] ...

  6. 【LeetCode】二分 binary_search(共58题)

    [4]Median of Two Sorted Arrays [29]Divide Two Integers [33]Search in Rotated Sorted Array [34]Find F ...

  7. Thinkphp 请求和响应

    一. Request对象获取方法 1. request() 助手函数获取 2. think\Request 类获取 3.利用框架注入Request对象  Request方法时单利方法 在think框架 ...

  8. vue兄弟组件之前传信

    1.使用vuex 2.子传父,父传子 3.使用中央事件总线 1.新建一个js文件,然后引入vue 实例化vue 最后暴露这个实例 2.在要用的组件内引入这个组件 3.通过vueEmit.$emit(' ...

  9. Java缓冲流写出数据实例

    public class BufferedWriterDemo throws IOException { public static void main(String[] args) throws I ...

  10. 牛客多校第一场 Random Point in Triangle

    https://ac.nowcoder.com/acm/contest/881/F 打表代码: #include<bits/stdc++.h> using namespace std; ] ...