基于各种基础数据结构的SPFA和各种优化
一、基于各种数据结构的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和各种优化的更多相关文章
- Vlc基础数据结构记录
1. Vlc基础数据结构 hongxianzhao@hotmail.com 1.1 基础数据结构 struct vlc_object_t,相关文件为src\misc\objects.c. 定义为: ...
- Flink内存管理源代码解读之基础数据结构
概述 在分布式实时计算领域,怎样让框架/引擎足够高效地在内存中存取.处理海量数据是一个非常棘手的问题.在应对这一问题上Flink无疑是做得非常杰出的,Flink的自主内存管理设计或许比它自身的知名度更 ...
- redis 基础数据结构实现
参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...
- redis基础数据结构及编码方式
redis基础数据结构和编码方式 一.基础数据结构 1)简单动态字符串 2)双端链表 3)字典 4)跳跃表 5)整数集合 6)压缩列表 二.对象类型与编码 在redis的数据库中创建一个新的键值对时, ...
- Redis基础——剖析基础数据结构及其用法
这是一个系列的文章,打算把Redis的基础数据结构.高级数据结构.持久化的方式以及高可用的方式都讲一遍,公众号会比其他的平台提前更新,感兴趣的可以提前关注,「SH的全栈笔记」,下面开始正文. 如果你是 ...
- 基于php基础语言编写的小程序之计算器
基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...
- 【UOJ#228】基础数据结构练习题 线段树
#228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...
- 理解 OpenStack + Ceph (4):Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...
- hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)
基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...
随机推荐
- 移动端300ms延迟原理,穿透、遮罩层滑动导致下面滑动总结
遮罩层滑动导致下面滑动 1,阻止弹层滑动,使用默认事件,使用这种方式弹层不能滑动 document.getElementById("model").addEventListener ...
- 2018-2-13-win10-uwp-读写csv-
title author date CreateTime categories win10 uwp 读写csv lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17 ...
- How to compile and install Linux Kernel 5.1.2 from source code
How to compile and install Linux Kernel 5.1.2 from source code Compiling a custom kernel has its adv ...
- 基于impi zabbix监控r720 测试过程
1.F2进入服务器bios 修改network 使这台服务器能够被远程访问. 2.在远程的centos 7 服务器上安装 impitool工具包 #ipmitool -I lanplus -H X ...
- RAS
Reliability 高可靠性 Availability 高可用性 Serviceability 高服务性
- group_by
1.按照一个列或者多个列对数据分组 2.对每个组进行聚合操作 3. 对聚合后的结果进行判断 1. select avg(score) as score from teacher 2. select ...
- jquery 模态对话框传值,删除,新增表格行
个人的练习代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Final修饰的字段是否可以通过反射设置值
案发现场 经常听说final修饰的字段是常量不能改变的他的值,但是以外发现 Integer.java源码中的字段“value”是final,但是可以通过反射改变他的值. public final cl ...
- word从任意页设置页码
把所有页都设置页码 首先设置分隔符,下一页 在第二节中,找到插入页码,设置起始页码为1即可
- mycat操作mysql示例之分库
准备工作: 服务器192.168.96.12,centos7, jdk,mysql5.7,mycat1.6.x,navicat 搭建步骤: 1.在服务器192.168.96.12服务器上安装mysql ...