Dijkstra的堆优化
先附上一个例题:P3371 【模板】单源最短路径
一眼扫去,最短路。。。
spfa可行,但是今天的主题是Dijkstra:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 10010
#define MAXM 500010
#define MAX 999999999
using namespace std;
int n,m,s,c=1;
int head[MAXN],path[MAXN];
bool vis[MAXN];
struct node{
int next,to,w;
}a[MAXM<<1];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void add(int u,int v,int w){
a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
}
void dijkstra(){
for(int i=1;i<=n;i++){path[i]=MAX;vis[i]=false;}
path[s]=0;
for(int i=1,k,v;i<=n;i++){
k=-1;
for(int j=1;j<=n;j++)if(!vis[j]&&(k==-1||path[k]>path[j]))k=j;
if(k==-1)break;
vis[k]=true;
for(int j=head[k];j;j=a[j].next){
v=a[j].to;
if(!vis[v]&&path[v]>path[k]+a[j].w)path[v]=path[k]+a[j].w;
}
}
for(int i=1;i<=n;i++)printf("%d ",path[i]==MAX?2147483647:path[i]);
printf("\n");
}
int main(){
int u,v,w;
n=read();m=read();s=read();
for(int i=1;i<=m;i++){
u=read();v=read();w=read();
add(u,v,w);
}
dijkstra();
return 0;
}
然而,遇上某些题,n<=100,000,怎么办?
这时候,堆优化就出场了。
堆优化:
堆优化,即用堆来实现O( log2n )时间内找到到起点最短的未被松弛的点。
当然,你需要自定义结构体。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#define MAXN 10010
#define MAXM 500010
#define MAX 999999999
using namespace std;
int n,m,s,c=1;
int head[MAXN],path[MAXN];
bool vis[MAXN];
struct node{
int next,to,w;
}a[MAXM];
struct Point{
int x,dis;
bool operator <(const Point &p)const{
return dis>p.dis;
}
};
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void add(int u,int v,int w){
a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
}
void dijkstra(){
Point u,v;
priority_queue<Point> q;
for(int i=1;i<=n;i++){path[i]=MAX;vis[i]=false;}
u.x=s;u.dis=path[s]=0;
q.push(u);
while(!q.empty()){
u=q.top();
q.pop();
if(!vis[u.x]){
vis[u.x]=true;
for(int i=head[u.x];i;i=a[i].next){
v.x=a[i].to;
if(!vis[v.x]){
path[v.x]=min(path[v.x],path[u.x]+a[i].w);
v.dis=u.dis+a[i].w;
q.push(v);
}
}
}
}
for(int i=1;i<=n;i++)printf("%d ",path[i]==MAX?2147483647:path[i]);
printf("\n");
}
int main(){
int u,v,w;
n=read();m=read();s=read();
for(int i=1;i<=m;i++){
u=read();v=read();w=read();
add(u,v,w);
}
dijkstra();
return 0;
}
不得不说,这玩意效率虽然没有spfa+SLF高,但是遇上了这题,你也是无可奈何地用它:
后记:
附上洛谷上的两次提交:(P3371)
朴素Dijkstra:Accepted 100
1036ms / 7.77MB
代码:1.11KB C++
Dijkstra+堆优化:Accepted 100
348ms / 9.49MB
代码:1.3KB C++
明显快了不少。
不过出题人没事干也不会卡你的spfa,至少在NOIP这种考试中。。。
Dijkstra的堆优化的更多相关文章
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- Dijkstra及其堆优化
朴素Dijkstra #include<bits/stdc++.h> using namespace std; const int inf=9999999; bool book[105]; ...
- 洛谷 P4779 【dijkstra】+(堆优化)+(链式前向星) (模板题)
<题目链接> 题目描述 给定一个 N 个点, M 条有向边的带非负权图,请你计算从 S 出发,到每个点的距离. 数据保证你能从 S 出发到任意点. 输入格式: 第一行为三个正整数 N,M, ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- Dijkstra+优先队列 堆优化
关于堆优化 传统\(Dijkstra\),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂(\(O(V2+E) ...
- Dijkstra算法堆优化
转自 https://blog.csdn.net/qq_41754350/article/details/83210517 再求单源最短路径时,算法有优劣之分,个人认为在时间方面 朴素dijkstra ...
- Dijkstra算法堆优化详解
DIJ算法的堆优化 DIJ算法的时间复杂度是\(O(n^2)\)的,在一些题目中,这个复杂度显然不满足要求.所以我们需要继续探讨DIJ算法的优化方式. 堆优化的原理 堆优化,顾名思义,就是用堆进行优化 ...
- 最短路-朴素版Dijkstra算法&堆优化版的Dijkstra
朴素版Dijkstra 目标 找到从一个点到其他点的最短距离 思路 ①初始化距离dist数组,将起点dist距离设为0,其他点的距离设为无穷(就是很大的值) ②for循环遍历n次,每层循环里找出不在S ...
- Dijkstra和堆优化
Dijkstra算法 由于我之前一直记的迪杰斯特拉的翻译导致我把dijkstra写成了dijstra--所以下文#define dijstra dijkstra 我以后叫她迪杰克斯歘! Dijskra ...
随机推荐
- [java基础] 002 - 位运算符的详解和妙用
一:位运算符详解 位运算符主要用来对操作数二进制的位进行运算.按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值. Java 语言中的位运算符分为位逻辑运算符和位移运算符两类, ...
- python在程序中通过Windows打开文件
import os os.startfile(r'D:\test_input.html')
- How To Commit Just One Data Block Changes In Oracle Forms
You have an Oracle Form in which you have multiple data blocks and requirement is to commit just one ...
- 区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛
区间最小值(2) Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Subm ...
- 关于Web应用和容器的指纹收集以及自动化软件的制作
一次对Web应用的渗透,九成都是从信息收集开始,所以信息收集就显得尤为重要.关键信息的收集可以使你在后期渗透的时候更加的得心应手,把渗透比喻成走黑暗迷宫的话,那信息收集可以帮你点亮迷宫的大部分地图. ...
- CLI/C++中混合类的使用【转】
http://www.cppblog.com/mzty/archive/2007/12/24/39517.html CLI/C++中混合类的使用 一 混合类 所谓混合类是指CLI/C++中native ...
- TensorFlow笔记一 :测试和TFboard使用
一 .第一个TF python3.6 import tensorflow as tf x=2 y=3 node1=tf.add(x,y,name='node1') node2=tf.multiply ...
- 转: 三大WEB服务器对比分析(apache ,lighttpd,nginx) (2008年的旧文,仅供参考之用)
from: http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html 三大WEB服务器对比分析(apache ,lighttp ...
- java 环境变量配置 Mac
大家在windows里面配置JDK环境变量很容易,但是如果要在mac里面配置JDK环境变量和windows里面有所不同,具体如下: 第一: mac OS里面自带jdk,不过是1.6的版本,现在很多人使 ...
- Java排序算法(三):直接插入排序
[基本思想] 关键:在前面已经排好序的序列中找到合适的插入位置 步骤: 1. 从第一个元素開始,该元素能够觉得已经排好序. 2. 取出下一个元素.在已经排好序的元素序列中从后往前扫描进行比較. 3. ...