dijkstra算法的堆优化
普通的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算法的堆优化的更多相关文章
- 单源最短路径:Dijkstra算法(堆优化)
前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...
- 【Luogu P4779】dijkstra算法的堆优化
Luogu P4779 利用堆/优先队列快速取得权值最小的点. 在稠密图中的表现比SPFA要优秀. #include<iostream> #include<cstdio> #i ...
- dijkstra最短路算法(堆优化)
这个算法不能处理负边情况,有负边,请转到Floyd算法或SPFA算法(SPFA不能处理负环,但能判断负环) SPFA(SLF优化):https://www.cnblogs.com/yifan0305/ ...
- 关于dijkstra的小根堆优化
YY引言 在NOI2018D1T1中出现了一些很震惊的情况,D1T1可以用最短路解决,但是大部分人都在用熟知的SPFA求解最短路.而SPFA的最坏复杂度能够被卡到$O(VE)$.就是边的数量乘以点的数 ...
- Dijkstra算法与堆(C++)
Dijkstra算法用于解决单源最短路径问题,通过逐个收录顶点来确保得到以收录顶点的路径长度为最短. 图片来自陈越姥姥的数据结构课程:https://mooc.study.163.com/l ...
- prim最小生成树算法(堆优化)
prim算法原理和dijkstra算法差不多,依然不能处理负边 1 #include<bits/stdc++.h> 2 using namespace std; 3 struct edge ...
- dijkstra算法之优先队列优化
github地址:https://github.com/muzhailong/dijkstra-PriorityQueue 1.题目 分析与解题思路 dijkstra算法是典型的用来解决单源最短路径的 ...
- 单源最短路问题 Dijkstra 算法(朴素+堆)
选择某一个点开始,每次去找这个点的最短边,然后再从这个开始不断迭代,更新距离. 代码: 朴素(vector存图) #include <iostream> #include <cstd ...
- 单源最短路-dijkstra算法(未优化)
bool used[maxn]; int g[maxn][maxn]; // 边未联系的填充为INF int d[maxn]; void dijkstra(int s){ memset(g,false ...
随机推荐
- c语言中static 函数和普通函数的区别
C程序一直由下列部分组成: 1)正文段——CPU执行的机器指令部分:一个程序只有一个副本:只读,防止程序由于意外事故而修改自身指令: 2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放 ...
- Eureka与Zookeeper的区别
ACID与ACP的介绍
- 【More Effective C++ 条款4】非必要不提供default constructor
1)default constructor:在没有任何外来信息的情况下将对象初始化 2)但是有些对象如果没有外来信息,就没有办法完成初始化动作,那么这些对象,就没有必要提供default constr ...
- R与金钱游戏:均线黄金交叉1
双11临近的我发现自己真的很穷很穷很穷(重要的问题说三遍)-- 贫穷催人上进.于是我就寻思着在空闲时间自己捣鼓一下钱生钱的游戏是怎么玩的,毕竟就算注定做韭菜也要做一根有知识有理想的韭菜. 第一个要玩的 ...
- git账户配置
一.生成github的ssh key ssh-keygen ssh-keygen -t rsa -f ~/.ssh/zzf073_rsa -C zzf073@163.com 二.配置账户公钥 1.查看 ...
- (转)WEB页面导出为Word文档后分页&横向打印的方法
<html> <HEAD> <title>WEB页面导出为Word文档后分页&横向打印的方法 </title> < ...
- css权重等级
1.问题起因(在一次偶然编写css发现的,.div2 p>.div1 p>.p1,然后做了测试并找查相关资料) 2.解决方案 首先看哪一级的权重高 1.!important,加在样式属性值 ...
- Python - 基本数据类型 - 第二天
Python3 基本数据类型 Python 中的变量不需要声明.每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 在 Python 中,变量就是变量,它没有类型,我们所说的"类型& ...
- netty框架概述
概述 最近在学习netty的相关知识,也在看netty的源码,光看不练假把式,所以也正好利用自己学习的机会写几篇netty的分析文章,主要还是一些源码解析的文章,一方面有输出会促使自己在看源码,学习原 ...
- EntityFramework 基类重写
/* * ------------------------------------------------------------------------------ * * 创 建 者:F_Gang ...