dijkstra的堆优化

这篇具有很好参考价值的文章主要介绍了dijkstra的堆优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

核心:priority_queue< pair<int,int> > 用优先队列来取最近的点,就不用遍历找点了

在pq中,是按pair的第一个元素(first)由大到小排序的,所以pair<距离,点号>,注意因为要的是最小值,所以距离要存负值
其实距离是纯纯的工具人,我们只是需要它来维持点的排序

每次取队首h,取出的就是dis最短的点
还要注意:
如果这个点的dis不等于h的dis,说明这个点在入队之后被更新了,那么我们就不用这个点了,直接continue;
因为后面会有个h2点比h1的dis更小,用h1更新就没有意义了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int> 

const int maxn=2e5;
int head[maxn],cnt;
ll dis[maxn];
int n,m,s;

struct node{
	int to,nxt;
	ll val;
}e[maxn];

void add(int u,int v,int w){
	e[++cnt].to=v;
	e[cnt].val=w;
	e[cnt].nxt=head[u];
	head[u]=cnt;	
}

void dijkstra(int s){
	priority_queue<pii> q;
	memset(dis,0x3f3f,sizeof dis);
	q.push({0,s});
	dis[s]=0;
	while(!q.empty())
	{
		int dh=q.top().first;
		int h=q.top().second;
		q.pop();
		if(dh+dis[h]) continue;            //dh是负的,如果不相等就跳过
		for(int i=head[h];i;i=e[i].nxt)
		{
			int t=e[i].to;
			if(dis[t]>dis[h]+e[i].val)
			{
				dis[t]=dis[h]+e[i].val;
				q.push({-dis[t],t});        //注意因为要从小到大排序,所以要存负距离
			}
		}
	}
	for(int i=1;i<=n;i++)  cout<<dis[i]<<" ";
}

int main(){
	cin>>n>>m>>s;
	while(m--){
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
	}
	dijkstra(s);
	return 0;
}

注意pq和pair的用法

pq队首是pq.top()

pair首元素是x.first,尾元素是x.second,没有括号

补充一下其他东西,当我们需要重新写一个新的向前星时,我们可以用

        memset(head,0,sizeof head);
        cnt=0;

来删去原来的边(重置head和cnt就行)

重载priority_queue

priority_queue<pii,vector<pii>,greater<pii> >文章来源地址https://www.toymoban.com/news/detail-485596.html

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int> 
 
const int maxn=2e5;
int head[maxn],cnt;
ll dis[maxn];
int n,m,s;
 
struct node{
	int to,nxt;
	ll val;
}e[maxn];
 
void add(int u,int v,int w){
	e[++cnt].to=v;
	e[cnt].val=w;
	e[cnt].nxt=head[u];
	head[u]=cnt;	
}
 
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> > q;
	memset(dis,0x3f3f,sizeof dis);
	q.push({0,s});
	dis[s]=0;
	while(!q.empty())
	{
		int dh=q.top().first;
		int h=q.top().second;
		q.pop();
		if(dh-dis[h]) continue;            
		for(int i=head[h];i;i=e[i].nxt)
		{
			int t=e[i].to;
			if(dis[t]>dis[h]+e[i].val)
			{
				dis[t]=dis[h]+e[i].val;
				q.push({dis[t],t});        //注意因为要从小到大排序,所以要存负距离
			}
		}
	}
	for(int i=1;i<=n;i++)  cout<<dis[i]<<" ";
}
 
int main(){
	cin>>n>>m>>s;
	while(m--){
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
	}
	dijkstra(s);
	return 0;
}

到了这里,关于dijkstra的堆优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ 优先队列 priority_queue 使用篇

    目录 1.储备知识    (1)数据结构:堆   (2)仿函数(函数对象)     [1]理解仿函数     [2]实现仿函数   (3)priority_queue理解     [1]什么是priority_queue (优先队列)?     [2]优先队列性质 2.priority_queue的参数理解(重要!!!)   (1)priority_queue的参数     [1]priority_queue类模板参数     [

    2024年03月12日
    浏览(72)
  • 『C++ - STL』之优先级队列( priority_queue )

    什么是优先级队列,从该名中可以知道他一定有队列的一定属性,即先入先出(LILO),而这里的优先级则可以判断出它的另一个特点就是可以按照一定的条件将符合该条件的先进行出队,这就是优先级队列; 而在数据结构中有一个支持该操作的结构 - 堆( heap ); 而在STL中,这个

    2024年02月07日
    浏览(33)
  • 【C++初阶】模拟实现优先级队列priority_queue

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 优先级队列顾名思义就是 按优先级出队列 priority_queue 是一个容器适配器,默认使用

    2024年02月10日
    浏览(29)
  • 【C++】详解priority_queue(优先级队列)与函数对象

    目录 一、priority_queue 的介绍和使用 1.1priority_queue 的介绍 2.2priority_queue 的使用 二、仿函数 2.1什么是仿函数 2.2仿函数的作用 三、函数对象的特点(知识点多) 3.1分析特点5(比较普通函数与函数对象) 3.1.1利用普通函数传递参数 拓展之:深度剖析函数利用模板的本质 3.1.2利用

    2024年02月08日
    浏览(30)
  • C++——优先级队列(priority_queue)的使用及实现

    目录 一.priority_queue的使用 1.1、基本介绍 1.2、优先级队列的定义 1.3、基本操作(常见接口的使用) 1.4、重写仿函数支持自定义数据类型 二.priority_queue的模拟实现 2.1、构造重要的调整算法 2.2、常见接口的实现 push() pop() top() empty()、size()  三.利用仿函数改进调整算法 我们之前

    2024年02月02日
    浏览(29)
  • 【C++】——栈和队列(stack、queue)及优先队列(priority_queue)的介绍和模拟实现

    今天我们来学习C++stl六大组件的其中一种,容器适配器,stack、queue及priority_queue都是容器适配器。我们循序渐进,接下来让我们先认识一下什么是容器适配器。 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该

    2024年02月08日
    浏览(34)
  • 【C++】STL使用仿函数控制优先级队列priority_queue

    本文章讲解C++STL的容器适配器:priority_queue的实现,并实现仿函数控制priority_queue底层。 priority_queue叫做优先级队列,它的底层结构是堆,在库中,默认生成的是大堆 在库的实现中,使用vector作为该优先级队列的适配容器。 由于priority_queue也是一个适配器,所以它的接口函数

    2024年02月16日
    浏览(34)
  • 【C++入门到精通】C++入门 —— priority_queue(STL)优先队列

    ⭕文章绑定了VS平台下std::priority_queue的源码,大家可以下载了解一下😍 前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象

    2024年02月12日
    浏览(32)
  • 【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现

    点进来的小伙伴不知道学过数据结构里的堆没有,如果学过的话,那就好说了,优先级队列就是堆,如果没学过,没关系,可以参考一下我之前写的一篇关于堆的博客,可以点进去看看:【数据结构】堆(包含堆排序和TOPK问题) 那么了解过堆了的话,我就不讲那么细致了,

    2024年02月16日
    浏览(37)
  • 【STL】priority_queue(优先级队列)详解及仿函数使用(附完整源码)

    1. priority_queue介绍和使用 1.1 priority_queue介绍 优先级队列也是在 queue 里: 因此和 queue 一样, priority_queue 也是一个容器适配器。priority_queue官方文档 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 类似于堆,在堆中可以随

    2024年02月08日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包