普通的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. CSS属性相关知识

    Css选择器 选择器的权重 在css中,哪个选择器的权重高,就走谁的样式. 标签选择器的权重是 1 Class选择器的权重是10 Id选择器的权重是100 行间样式的权重是1000 带有关键字 !im ...

  2. Extra:Variable Types

    文章著作权归作者所有.转载请联系作者,并在文中注明出处,给出原文链接. 本系列原更新于作者的github博客,这里给出链接. 在我们使用Cg或者HLSL进行shader编写的过程中,常常涉及到一些变量 ...

  3. [IOT] - 在树莓派的 Raspbian 系统中安装 .Net Core 3.0 运行环境

    之前在 Docker 中配置过 .Net Core 运行环境,地址:[IOT] - Raspberry Pi 4 Model B 系统初始化,Docker CE + .Net Core 开发环境配置 ...

  4. 【mybatis】标签条件中判断入参属性值是否包含子字符串

    可以直接使用 contains判断 <foreach collection="list" item="item" index="index&qu ...

  5. WPF 精修篇 长时间线程加取消功能

    原文:WPF 精修篇 长时间线程加取消功能 <Grid> <Grid.RowDefinitions> <RowDefinition Height="11*&qu ...

  6. MongoDB下载+安装+配置+错误解决方法

    下载 官网下载: https://www.mongodb.com/download-center/community Server=>Download 安装 下载完成后安装 建议下载根目录(下过 ...

  7. Springboot项目中pom.xml的Oracle配置错误问题

    这几天刚开始学习Springboot碰见各种坑啊,这里记录一个添加Oracle引用的解决方案. 前提:开发工具IDEA2019.2,SpringBoot,maven项目:Oracle版本是Oracle ...

  8. Sharding-Jdbc概念与使用技巧

    1. Sharding-Jdbc概念与使用技巧 此讲解版本为4.0.0-RC1,目前最新的版本 2019年5月21日发布 1.1. 绑定表 指分片规则一致的主表和子表.例如:t_order表和t_or ...

  9. getOwnPropertyDescriptor

    语法 Object.getOwnPropertyDescriptor(obj, prop) 参数 obj 需要查找的目标对象 prop 目标对象内属性名称 返回值 如果指定的属性存在于对象上,则返回其 ...

  10. Apache ActiveMQ 远程代码执行漏洞 (CVE-2016-3088) 复现

    漏洞复现 直接写 shell 写 shell 的话,需要写在 admin 或者 api 中,也就是需要登录,没有密码的话完成不了写 shell 操作. 该环境默认的口令为 admin/admin. 访 ...