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

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

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

这二者如何结合呢?

我们都知道。迪杰斯特拉算法每一步都需要找属于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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值