普通的dijkstra算法模板:

//数据结构
int g[LEN][LEN]; //邻接矩阵
int vis[LEN]; //标记是否访问
int dist[LEN] //源点到各点的距离 fill(dist,dist+LEN,MAX);
dist[s]=;
while(){
int u=-,d=MAX;
for(int i=;i<N;i++){
if(!vis[i] && dist[i]<d){
d=dist[i];
u=i;
}
}
if(u<) break;
vis[u]=;
for(int i=;i<N;i++) if(!vis[i]){
if(dist[u]+g[u][i]<dist[i]){
dist[i]=dist[u]+g[u][i];
}
}
}

为了能在“取出最小的dist”这一步实现优化,我们使用priority_queue进行优化。下面用cmp结构体重载括号运算符priority_queue进行改造:

struct cmp{
bool operator () (int a,int b){
return dist[a]>dist[b];
}
};
priority_queue<int,vector<int>,cmp> pq;

然后我们来看堆优化的dijkstra算法:

//数据结构
int g[LEN][LEN]; //邻接矩阵
int vis[LEN]; //标记是否访问
int dist[LEN] //源点到各点的距离
struct cmp{
bool operator () (int a,int b){
return dist[a]>dist[b];
}
};
priority_queue<int,vector<int>,cmp> pq; fill(dist,dist+LEN,MAX);
dist[s]=;
pq.push(s);
while(!pq.empty()){
int u=pq.top();
pq.pop();
if(vis[u]) continue
;
vis[u]=;
for(int i=;i<N;i++) if(!vis[i]){
if(dist[u]+g[u][i]<dist[i]){
dist[i]=dist[u]+g[u][i];
pq.push(i);
}
}
}

加粗的代码是未优化dijkstra所没有的。

每次更新结点,都把新的结点存到优先队列中去。

用一道例题练手。OJ链接:Travel Plan

AC代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map> #define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1010
#define MAX (1<<30)-1
#define V vector<int> using namespace std; int g_dist[LEN][LEN];
int g_cost[LEN][LEN];
int vis[LEN];
int dist[LEN];
int cost[LEN];
int pre[LEN]; struct cmp{
bool operator () (int a,int b){
return dist[a]>dist[b];
}
};
priority_queue<int,vector<int>,cmp> pq; int main(){
// freopen("1030.txt","r",stdin);
int n,m,s,e,i,j,a,b,c,d,t;
I("%d%d%d%d",&n,&m,&s,&e);
fill(g_dist[],g_dist[]+LEN*LEN,MAX);
FF(i,m){
I("%d%d%d%d",&a,&b,&c,&d);
g_dist[a][b]=c;
g_dist[b][a]=c;
g_cost[a][b]=d;
g_cost[b][a]=d;
}
fill(dist,dist+LEN,MAX);
fill(cost,cost+LEN,MAX);
cost[s]=;
pre[s]=-;
//加入堆优化
pq.push(s); //源点入队
dist[s]=;
while(!pq.empty()){
int u=pq.top();
pq.pop();
if(vis[u]) continue;
vis[u]=;
FF(i,n) if(!vis[i]){
if(dist[u]+g_dist[u][i]<dist[i] || (dist[u]+g_dist[u][i]==dist[i] && cost[u]+g_cost[u][i]<cost[i])){
dist[i]=dist[u]+g_dist[u][i];
cost[i]=cost[u]+g_cost[u][i];
pre[i]=u;
//如果通过u点更新了一个i点,那么i点入队。
pq.push(i);
}
}
}
vector<int> path;
i=e;
while(i!=-){
path.insert(path.begin(),i);
i=pre[i];
}
FF(i,path.size()) O("%d ",path[i]);
printf("%d %d\n",dist[e],cost[e]) ;
return ;
}

dijkstra算法的堆优化的更多相关文章

  1. 单源最短路径:Dijkstra算法(堆优化)

    前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...

  2. 【Luogu P4779】dijkstra算法的堆优化

    Luogu P4779 利用堆/优先队列快速取得权值最小的点. 在稠密图中的表现比SPFA要优秀. #include<iostream> #include<cstdio> #i ...

  3. dijkstra最短路算法(堆优化)

    这个算法不能处理负边情况,有负边,请转到Floyd算法或SPFA算法(SPFA不能处理负环,但能判断负环) SPFA(SLF优化):https://www.cnblogs.com/yifan0305/ ...

  4. 关于dijkstra的小根堆优化

    YY引言 在NOI2018D1T1中出现了一些很震惊的情况,D1T1可以用最短路解决,但是大部分人都在用熟知的SPFA求解最短路.而SPFA的最坏复杂度能够被卡到$O(VE)$.就是边的数量乘以点的数 ...

  5. Dijkstra算法与堆(C++)

    Dijkstra算法用于解决单源最短路径问题,通过逐个收录顶点来确保得到以收录顶点的路径长度为最短.      图片来自陈越姥姥的数据结构课程:https://mooc.study.163.com/l ...

  6. prim最小生成树算法(堆优化)

    prim算法原理和dijkstra算法差不多,依然不能处理负边 1 #include<bits/stdc++.h> 2 using namespace std; 3 struct edge ...

  7. dijkstra算法之优先队列优化

    github地址:https://github.com/muzhailong/dijkstra-PriorityQueue 1.题目 分析与解题思路 dijkstra算法是典型的用来解决单源最短路径的 ...

  8. 单源最短路问题 Dijkstra 算法(朴素+堆)

    选择某一个点开始,每次去找这个点的最短边,然后再从这个开始不断迭代,更新距离. 代码: 朴素(vector存图) #include <iostream> #include <cstd ...

  9. 单源最短路-dijkstra算法(未优化)

    bool used[maxn]; int g[maxn][maxn]; // 边未联系的填充为INF int d[maxn]; void dijkstra(int s){ memset(g,false ...

随机推荐

  1. SkyWalking6.2.0版本UI参数、告警参数、指标含义中文解释

    一.告警规则相关参数 二.SkyWalking UI相关参数CPM:每分钟请求调用的次数SLA: 服务等级协议(简称:SLA,全称:service level agreement).是在一定开销下为保 ...

  2. 2019-11-29-win10-uwp-手把手教你使用-asp-dotnet-core-做-cs-程序

    原文:2019-11-29-win10-uwp-手把手教你使用-asp-dotnet-core-做-cs-程序 title author date CreateTime categories win1 ...

  3. layui提示框事件

    使用layui提示框的时候遇到个问题,点击“确定”“取消”之类的按钮会执行里面的方法,但点击×就不会执行,所以在添加数据的时候出现个BUG,就是保存数据后点击弹出提示框的×,继续保存,如此循环,就可以 ...

  4. PIE SDK影像快速拼接

    1.算法功能简介 快速拼接是对若干幅互为邻接的遥感数字图像拼在一起,构成一幅整体影像的技术过程.PIE支持快速拼接算法功能的执行,下面对快速拼接算法功能进行介绍. 2.算法功能实现说明 2.1 实现步 ...

  5. 今天是JAVA诞生日

    今天是JAVA诞生日,祝贺!!! 1995年5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器,Java诞生. https://baike.baidu.com/it ...

  6. Java之路---Day17(数据结构)

    2019-11-04-23:03:13 目录: 1.常用的数据结构 2.栈 3.队列 4.数组 5.链表 6.红黑树 常用的数据结构: 包含:栈.队列.数组.链表和红黑树 栈: 栈:stack,又称堆 ...

  7. Linux 下的 mysql 自动备份

    Linux 下实现自动备份,主要就是编写好执行备份的 shell script( *.sh )文件,设好权限(可读,可执行).然后利用 Linux 定时任务 crontab 来执行备份脚本就可以了.以 ...

  8. 把JSON数据格式转换为Python的类对象

    JOSN字符串转换为自定义类实例对象 有时候我们有这种需求就是把一个JSON字符串转换为一个具体的Python类的实例,比如你接收到这样一个JSON字符串如下: {"Name": ...

  9. Vue-cli构建spa应用

    2.1 VUE-cli构建spa应用 npm install -g vue-cli Vue init webpack-simple demo vue init webpack demo2 如果在项目目 ...

  10. 基于windows 10打造的kali工具集

    基于windows 10打造的kali工具集.iso,适合于习惯使用windows的安全从业者.if you like it,please touch star! 作为安全从业主,Kali都是必备工具 ...