普通的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. 探索FFmpeg

    Part1 :FFmpeg简介 FFmpeg定义 FFmpeg是一款音视频编解码工具,为开发者提供了大量音视频处理接口. FF指的是"Fast Forward" FFmpeg历史 ...

  2. Mysql序列(八)—— group by排序问题

    在mysql中,group by默认会执行排序: By default, MySQL sorts GROUP BY col1, col2, ... queries as if you also inc ...

  3. Kafka学习笔记之K8S内filebeat传输到kafka报错带解决方案

    0x00 概述 filebeat非常轻量级,正常情况下占用的资源几乎都能忽略不计,但是部署后发现资源占用很大,所以怀疑是filebeat本身出了问题. 第一时间查看filebeat日志(默认路径/va ...

  4. NetCore HttpClient The SSL connection could not be established, see inner exception

    之前遇到一个问题 https://www.cnblogs.com/leoxjy/p/10201046.html 在centos 7.x  HttpClient访问会出问题  The SSL conne ...

  5. handle句柄

    若是你向我问起 Win32 程序设计中印象最深(最坑爹)的一个概念是什么,那么我会毫不犹豫地告诉你——句柄(Handles).究其原因,无论是 MSDN 还是 维基百科,对于“句柄”这个词的解说都显得 ...

  6. HTML5 下拉控件绑定数据

    <select id="CommunityList" class="form-control" > <option>請選擇社團</ ...

  7. Java集合Map基本方法

    jdk1.7 api中的方法摘要: 参考java集合大全图:https://www.cnblogs.com/xkzhangsanx/p/10889114.html Map为所有Map子类的接口.

  8. 微服务架构 ------ 插曲 Mybatis逆向工程

    1.首先是pom.xml, 我们需要引入需要的mvn插件 <?xml version="1.0" encoding="UTF-8"?> <pr ...

  9. Java 多线程编程——多线程

    如果要想在Java之中实现多线程的定义,那么就需要有一个专门的线程主体类进行线程的执行任务的定义,而这个主体类的定义是有要求的,必须实现特定的接口或者继承特定的父类才可以完成. 1. 继承Thread ...

  10. MySQL查询——select

    SELECT select的完整语法: select col1, col2,... # 业务查询的字段 from table_name # 选取的哪张表 [where single_condition ...