基于各种基础数据结构的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 ...
随机推荐
- ll字段 详解 文件权限
文件类型和权限 硬链接总数 属主用户名 属组组名 文件大小(字节) 上次修改时间 文件/目录名 drwxr-xr-x 15 lb lb 4096 10月 19 01:11 ./ drwxr-xr-x ...
- ls 显示目录下的内容和文件相关属性信息
1.命令功能 ls命令是“list directory contents”,显示当前目录下的内容和文件属性. 2.语法格式 ls [option] file ls 选项 文件名 3.选项说明 ...
- CreateMutex函数 (转)
CreateMutex函数 该函数找出当前系统是否已经存在指定进程的实例.如果没有则创建一个互斥体. CreateMutex()函数可用来创建一个有名或无名的互斥量对象,其函数原型为: HANDLE ...
- struts2的相关知识(实现原理、拦截器)
struts2的实现原理 客户端初始化一个指向Servlet容器(例如Tomcat)的请求 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的 ...
- 【leetcode】1042. Flower Planting With No Adjacent
题目如下: You have N gardens, labelled 1 to N. In each garden, you want to plant one of 4 types of flow ...
- URLEncode解决url中有特殊字符的问题
问题:图片上传后的url地址中有&等特殊字符,页面传到后端时被自动处理成了& 解决:前端对url进行URLEncode,后端收到后进行URLDecode 总结:需要在请求u ...
- 在idea中把springboot项目打成jar包遇到的问题(没有主清单属性)
正确的姿势:<plugin> <groupId>org.springframework.boot</groupId> <artifactId>sprin ...
- Jenkines邮件中添加图片
1.在Jenkins的邮件插件 Email-ext中的Default Content内容编写html文件,简单模板如下: <html> <head> </head&g ...
- 使用tinymce编辑器从word保持原格式复制粘贴的办法
官网地址http://ueditor.baidu.com Git 地址 https://github.com/fex-team/ueditor 参考博客地址 http://blog.ncmem.com ...
- android设置系统默认开机时间
1.设置RTC时间,该时间是如果RCT时钟断电以后使用的默认时间 Android L之前: \alps\mediatek\custom\[project]\preloader\ inc\cust_rt ...