迪杰斯特拉+优先队列优化

优先队列:是一种特殊的队列。这种队列会自动的将队列里面的元素进行排序,这种排序是可定义的。

迪杰斯特拉:这个算法我之前的博客有讲过,所以不重复赘述。当了看这篇文章的人肯定是会这个算法的。

这二者如何结合呢?

我们都知道。迪杰斯特拉算法每一步都需要找属于Vb集合中找一个距离最小的点把他加入到Va集合中,每一次都需要找。所以普通版的迪杰斯特拉算法的时间复杂度是n*n。

因为每一步都需要找距离最小的点。我们这时候不妨考虑一下用优先队列来优化这个找最小的过程。这样时间复杂度就降到的n*logn。

下面上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;

#define INF 0x3f3f3f

struct Node{    //这个结构体是队列的基本元素。
	int num;	// 点编号
	int val;	// 点的权值
}nod;  

priority_queue<Node> qq;	//定义优先队列

bool operator < (Node a ,Node b){	//这是优先队列的定义方法。和定义sort排序有点不同,他和sort是相反的。这里定义的是按照val值最小的在前排序
	if(a.val == b.val) return a.num > b.num;
	return a.val > b.val;
}

int book[100]; //没用到
int dis[100];	//答案数组
int D[100][100];	//地图
int V,E;	//点的个数 和边的个数

int main(){
	int a,b,d;
	while(cin >> V >> E && V && E){
		while(!qq.empty()) qq.pop();  //清空优先队列
		memset(book,0,sizeof(book));
		memset(D,-1,sizeof(D));		//若D【i】【j】为-1表示i到j这两个点不通
		for(int i = 0; i < E ; i ++){
			cin >> a >> b >> d ;
			D[a][b] = D[b][a] = d;
		}
		for(int i = 2;i <= V ; i ++)
		dis[i] = INF;
		dis[1] = 0;
		nod.num = 1;
		nod.val = 0;
		qq.push(nod);	//最开始的时候只有初始点1,所以把1加入优先队列
		while(!qq.empty()){
			for(int i = 2 ; i <= V ; i++){
				if(D[qq.top().num][i] != -1 && dis[i] > dis[qq.top().num]+D[qq.top().num][i]){ // 松弛操作。
					dis[i] = dis[qq.top().num] + D[qq.top().num][i];
					nod.num = i;
					nod.val = dis[i];
					qq.push(nod); // 把点加入到
				}
			}
			qq.pop();
		}
	
			cout << dis[V] << endl;
		
	}
	return 0;
}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
很抱歉,根据提供的引用内容,没有找到关于迪杰斯特拉算法树状数组优化的信息。但是,我可以为您介绍一下迪杰斯特拉算法和树状数组的基本概念和应。 迪杰斯特拉算法,也称为狄克斯特拉算法,是一种用于解决图中最短路径问题的算法。该算法的基本思想是从起点开始,逐扩展到距离起点更远的节点,直到到达终点为止。在扩展的过程中,通过比较不同路径的距离,选择距离最短的路径进行扩展,直到到达终点。 树状数组,也称为二叉索引树,是一种用于高效维护序列前缀和的数据结构。该数据结构可以在O(log n)的时间内完成单点修改和区间查询操作,因此被广泛应用于解决各种算法问题,如逆序对问题、区间最大值/最小值问题等。 虽然迪杰斯特拉算法和树状数组看似没有直接关系,但是在解决某些特定的问题时,两者可以结合使用,以达到更高效的解决方案。例如,在解决带权图最短路径问题时,可以使用迪杰斯特拉算法结合树状数组进行优化,以达到更快的计算速度。 具体来说,可以使用树状数组维护一个优先队列,用于存储当前已经扩展的节点和它们的距离。在每次扩展节点时,可以使用树状数组快速找到距离最小的节点,并将其从队列中删除。这样可以避免使用传统的堆数据结构,从而提高算法的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值