关于Dijkstra三种堆速度的研究
三种堆分别是std::priority_queue pbds::priority_queue(pairing_heap_tag) zkw线段树(加入了剪枝,即modify函数里当兄弟节点的value比自己小的时候break,因为再往上的最小值肯定由兄弟节点贡献)
为什么没有手写的paring_heap和binary_heap?大概没人会手写吧 实际上是因为我不会
结论大概是
不开O2时的用时:zkw线段树 < pbds::pq < std::pq
开O2时:std::pq 远小于 zkw线段树 < pbds::pq(稠密图zkw线段树的速度跟std::pq相近 且pbds::pq快于std::pq(因为点数较小所以实际差别并不大))
鬼知道std::pq吸氧以后为什么会快那么多
//gen
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+7;
vector<int>G[MAXN];
inline void add(int u, int v) {G[u].insert(lower_bound(G[u].begin(), G[u].end(), v), v);
}
char wbuf[50<<20], *p2 = wbuf;
inline void print(int x, int y, int z) {static int sta[25], top; top = 0;while(x) sta[++top] = x % 10, x /= 10;while(top) *p2++ = sta[top--] + '0';*p2++ = ' ';while(y) sta[++top] = y % 10, y /= 10;while(top) *p2++ = sta[top--] + '0';*p2++ = ' ';while(z) sta[++top] = z % 10, z /= 10;while(top) *p2++ = sta[top--] + '0';*p2++ = '\n';
}
int main(void) {freopen("data.in", "w", stdout);mt19937 Rand((unsigned)(new char));int n, m;n = 3e5, m = 4e5;printf("%d %d %d\n", n, m, 1);for(int i = 1; i < n; ++i) add(i, i+1);for(int i = n; i <= m; ++i) {int u, v;do {u = Rand()%n+1, v = Rand()%n+1; } while(u == v || binary_search(G[u].begin(), G[u].end(), v));add(u, v);}for(int i = 1; i <= n; ++i) {for(auto it = G[i].begin(); it != G[i].end(); ++it) {print(i, *it, Rand()%1000+1);}}fwrite(wbuf, 1, p2 - wbuf, stdout);return 0;
}
//runner
#include <bits/stdc++.h>
using namespace std;
int cnt = 0;
int main(void) {system("g++ test.cpp -o test.exe -std=c++11");system("g++ test.cpp -o testO2.exe -O2 -std=c++11");system("g++ gen.cpp -o gen.exe -std=c++11");while (1) {printf("Case %d:\n", ++cnt);system("gen.exe");puts("O2");system("testO2.exe");puts("Normal");system("test.exe");puts("");}return 0;
}
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
#define mp make_pair
#define value first
#define mark second
const int MAXN = 3e5 + 7;
#define lson (o<<1)
#define rson (o<<1|1)
typedef pair<int, int> pii;
int dis[MAXN], head[MAXN], n, m, s, t, tot, vis[MAXN];
struct ZkwHeap {pii Node[1 << 21];int M;inline void pushup(int o) {Node[o] = Node[lson].value < Node[rson].value ? Node[lson] : Node[rson];}inline void build(int n) {for (M = 1; M < n; M <<= 1);for (int i = 1; i <= (M << 1) - 1; ++i)Node[i].value = 0x3f3f3f3f;for (int i = 1; i <= n; ++i) Node[i + M].mark = i, dis[i] = 0x3f3f3f3f;}inline int tpos() {return Node[1].mark;}inline void modify(int pos, int val, bool flag) {for (Node[pos += M].value = val; pos != 1; pos >>= 1) {pushup(pos >> 1);if (flag && Node[pos ^ 1].value < Node[pos].value) break;}}inline int pop() {int ret = Node[1].value;modify(Node[1].mark, 0x3f3f3f3f, 0);return ret;}
} tree;
struct Edge {int v, w, next;
} G[MAXN << 2];
inline void add(int u, int v, int w) {G[++tot] = (Edge) {v, w, head[u]}; head[u] = tot;
}
std::priority_queue<pii, vector<pii>, greater<pii> >q;
typedef __gnu_pbds::priority_queue<pii, greater<pii>, pairing_heap_tag> heap;
heap::point_iterator it[MAXN];
heap q1;
unsigned long long ans[3];
void dijkstra(int s) {for(int i = 1; i <= n; ++i) dis[i] = 0x3f3f3f3f;dis[s] = 0;q.push(mp(0, s));while (!q.empty()) {pii x = q.top(); int u = x.second; q.pop();if (vis[u]) continue;vis[u] = 1;for (int v, w, i = head[u]; i; i = G[i].next) {v = G[i].v, w = G[i].w;if (dis[u] + w < dis[v]) {dis[v] = dis[u] + w;if (!vis[v]) q.push(mp(dis[v], v));}}}for (int i = 1; i <= n; ++i) ans[0] = (ans[0] + dis[i] * i);
}void Dijkstra(int s) {for(int i = 1; i <= n; ++i) dis[i] = 0x3f3f3f3f;dis[s] = 0;q1.push(mp(0, s));while (!q1.empty()) {pii x = q1.top(); int u = x.second; q1.pop();for (int v, w, i = head[u]; i; i = G[i].next) {v = G[i].v, w = G[i].w;if (dis[u] + w < dis[v]) {dis[v] = dis[u] + w;if (it[v] == 0) it[v] = q1.push(mp(dis[v], v));else q1.modify(it[v], mp(dis[v], v));}}}for (int i = 1; i <= n; ++i) ans[1] = (ans[1] + dis[i] * i);
}
void DIjkstra(int s) {tree.build(n);tree.modify(s, 0, 0);for (int u, v, w, k = 2; k <= n; ++k) {dis[u = tree.tpos()] = tree.pop();for (int i = head[u]; i; i = G[i].next) {v = G[i].v, w = G[i].w;if (dis[u] + w < dis[v]) {dis[v] = dis[u] + w;tree.modify(v, dis[v], 1);}}}for (int i = 1; i <= n; ++i) ans[2] = (ans[2] + dis[i] * i);
}
char buf[50 << 20], *p1 = buf;
inline void read(int &x, int &y, int &z) {x = y = z = 0;while (!isdigit(*p1)) ++p1;while (isdigit(*p1)) x = x * 10 + (*p1++) - '0';while (!isdigit(*p1)) ++p1;while (isdigit(*p1)) y = y * 10 + (*p1++) - '0';while (!isdigit(*p1)) ++p1;while (isdigit(*p1)) z = z * 10 + (*p1++) - '0';
}
int main(void) {freopen("data.in", "r", stdin);scanf("%d %d %d", &n, &m, &s);fread(buf, 1, 50 << 20, stdin);while (m--) {int u, v, w;read(u, v, w);add(u, v, w);}double tim1 = clock();dijkstra(1);double tim2 = clock();Dijkstra(1);double tim3 = clock();DIjkstra(1);double tim4 = clock();cerr << ans[0] << endl << ans[1] << endl << ans[2] << endl;cerr << "std::pq " << (tim2 - tim1) << endl;cerr << "pbds::pq " << (tim3 - tim2) << endl;cerr << "zkwsgt " << (tim4 - tim3) << endl;return 0;
}
转载于:https://www.cnblogs.com/storz/p/10190984.html
关于Dijkstra三种堆速度的研究相关推荐
- 10-4 5-4 查询至少生产三种不同速度PC的厂商 (20 分)
一:上码 -- 查询至少生产三种不同速度PC的厂商-- 分析:1.联合pc和product表,字段为厂商和速度 表1 -- 2.按厂商名字进行分组统计厂商的个数,筛选条件为个数大于3的 表2 -- 3 ...
- ReviewForJob——二叉堆优先队列的实现(三种堆节点类型——int + struct HeapNode + struct HeapNode*)
[0]README 1)本文旨在给出 二叉堆优先队列的实现 的代码实现和分析, 而堆节点类型 不外乎三种: 一, 基本类型如int: 二,结构体类型 struct HeapNode: 三,结构体指针类 ...
- 【电力电子】【2015】基于输出总谐波失真的三种逆变器的比较研究
本文为美国密苏里科技大学(作者:PATERRSON THOMAS)的硕士论文,共50页. 本文以三种电力电子式逆变器为研究对象,从输出电压和输出电流的总谐波失真角度分析了它们的性能.首先,对单H桥逆变 ...
- 浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程
昨天学了进程控制,就这三种特殊的进程研究了一下,其中也借鉴了一些前人总计的经验. 1.孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这里子进程的父进程就是init进程( ...
- 【opencv学习笔记】第五篇:访问图像中像素的三种方式、ROI区域图像叠加和图像混合
1. 访问图像中像素的三种方式 任何图像处理算法,都是从操作每个像素开始的.在OpenCV中,提供了三种访问每个像素的方法. 方法1:指针访问:C操作符[] 方法2:迭代器iterator 方法3:动 ...
- 桥接、NAT、HOST-ONLY三种网络模式的区别详解
在做虚拟机测试的过程中,突然发现虚拟机ping不通主机于是进行了三种网络模式的研究. 桥接: 简而言之桥接就是指:就是通过一台设备(可能不止一个)把几个网络串起来形成的连接.这边主要介绍虚拟机所采用的 ...
- 总结windows下堆溢出的三种利用方式
创建时间:2004-04-08 文章属性:转载 文章提交:watercloud (watercloud_at_xfocus.org) 原文由Leven发在网络编程版: https://www.xfoc ...
- List数组,string数组,Dictionary字典三种contain方法的查询速度
在生成随机不重复数时要判断生成的数是否已生成过,这时就要和原来生成的数进行比较是否有重复,有以下三种方法 1. list数组采用contains()方法 2.string数组采用contains()方 ...
- 如何测量智能产品的AI智商水平,论AI的三种智商 |未来研究
前言:本文是未来智能实验室关于人工智能智商的最新研究文章,主要提出智能系统的智能水平会因为测试目的的不同,产生三种不同的智商类型,针对这三种AI智商,本文也提出对应的测试方法和数学公式.相关英文论文与 ...
最新文章
- 程序员修炼之道阅读笔记01
- iap如何初始化_IAP超级详解
- c语言数据结构 自测卷答案,《c语言数据结构》第2章 自测卷答案
- hook koa web 码云_gitee码云使用webhook
- windows系统-函数的条件分支实现用汇编语言解释
- 透视变换--图像拼接
- postman连接mysql执行操作
- springboot hibernate 缓存不更新_spring boot 整合 ehcache
- php原生的异步请求,原生JavaScript实现Ajax异步请求
- 学习笔记:Unity战斗卡牌游戏(三)-----代码加载预设 及 Tween动画使用及播放回掉...
- echarts-市地图
- Bat清理Chrome谷歌浏览器所有缓存
- 使用JQuery.slideBox实现图片滚动效果
- VS2022 安装 .NET Framework 4.0的方法
- db2 windows linux,Migrate DB2 v9 on windows to DB2 v10.5 on linux
- 动态链接 lazy binding 的原理与 GOT 表的保留表项
- 图解系统(六)——调度算法
- maven 配置多个仓库
- Win7超级终端查看单片机printf输出
- 一个向上帝买了挂的男人
热门文章
- 聚奎中学2021高考成绩查询,江津2017全体高考考生的喜报
- java后台生成excel_Java后台生成Excel前台下载
- python刷新显示_Python在同一位置刷新显示进度信息
- 21天Jmeter打卡day15 配置元件之用户定义的变量
- mysql双主启停_Mysql 多实例配置与启停
- 深圳爱思拓大数据 网站_建议收藏!13个大数据学习网站很少人知道!附大数据自学资料分享...
- 需求跟踪矩阵模板_大连电视台采用无跟踪虚拟技术升级多套节目
- java后端服务运行原理_web服务的后台工作原理
- Linux系统mongdb还原数据库,MongoDB备份与恢复
- Java中对查出的数据计数_基础算法7:从数据库某个字段中取出现次数最多的几条数据形成“热门xxx”...