普通的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. Git基础-第2章

    简单的Git基础概念: repository: 仓库 track:  跟踪 stage: 暂存 commit:    提交 push:        推送 pull:    拉取 一.获取Git仓库 ...

  2. oracle批量新增更新数据

    本博客介绍一下Oracle批量新增数据和更新数据的sql写法,业务场景是这样的,往一张关联表里批量新增更新数据,然后,下面介绍一下批量新增和更新的写法: 批量新增数据 对于批量新增数据,介绍两种方法 ...

  3. 转 Pytorch 教学资料

    本文收集了大量PyTorch项目(备查) 转自:https://blog.csdn.net/fuckliuwenl/article/details/80554182 目录: 入门系列教程 入门实例 图 ...

  4. 用JavaScript带你体验V8引擎解析标识符

    上一篇讲了字符串的解析过程,这一篇来讲讲标识符(IDENTIFIER)的解析. 先上知识点,标识符的扫描分为快解析和慢解析,一旦出现Ascii编码大于127的字符或者转义字符,会进入慢解析,略微影响性 ...

  5. [转] linux 查找文本过滤grep正则表达式命令详解用法

    grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用 ...

  6. Java-Iterator遍历集合

    import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Ite ...

  7. C# 与 Java 的一些差异

    如果你是 Java 开发人员,则可以在 Xamarin 平台上充分利用你的技能和现有代码,同时获得 C# 的代码重用优势.你会发现 C# 语法与 Java 语法非常相似,这两种语言提供非常类似的功能. ...

  8. Oracle数据库触发器

    第一次写触发器,浪费了一个小时,少了一个;编译不通过 当A表有更新或插入数据时,则触发器执行向B表插入对应条件的数据1 CREATE OR REPLACE TRIGGER Test -- 触发器名称 ...

  9. checkbox实现单选

    脚本: function bb(obj,name) { var aa = document.getElementsByName(name); for (var i = 0; i < aa.len ...

  10. Salesforce LWC学习(一)Salesforce DX配置

    LWC: Create a Salesforce DX Project and Lightning Web Component:https://www.youtube.com/watch?v=p268 ...