Dijkstra算法堆优化求最短路径问题

                              Dijkstra算法堆优化求最短路径问题

                                                                                                                                                                                                                                   ——HM

 

Dijkstra算法在竞赛中较为常见了,(但终究没有SPFA跑得快)堆优化后更是使它的效率更上了一层楼(又是能超过SPFA),那么怎样进行堆优化呢?

还不会纯Dijkstra的人点这Dijkstra

堆优化的Dijkstra算法就是用堆每次弹出最小值来代替每轮要进行的最短边的查找。直接搜索的时间复杂度为O(m),而堆优化后会降到O(logm),大大减小了时间复杂度。

下面来讲一下堆优化后的Dijkstra时间复杂度。这点上很多人都议论纷纷,有的说O(MlogM),有的说(MlogN),有的说O((M+N)logM),而我个人比较赞同O((M+N)logM),其中M为边数,N为点数,我们可以知道,堆搜索最短边复杂度为O(MlogM),因为要搜索单点所到的所有边,所以堆中有M个点代表边权,所以在跑最短路时复杂度为O(MlogM),而开头要初始化堆 所用时间为O(NlogM),加起来便成为了O((M+N)logM)。当然这只是个人观点,如有不同意见欢迎在讨论区中发表高见。

最后时标程,由于本人水平不高且懒惰,用邻接矩阵来储存且用的是STL中的优先级队列,没有写手打堆,这里建议用邻接表或链式前向星来储存。

AC代码:

#include <bits/stdc++.h>
const int INF=0x3f3f3f3f;
using namespace std;

struct node{
	int data,pos;
	
	node(int x,int y){data=x;pos=y;}
	
	bool operator <(const node &a) const {
		return data>a.data;
	}
};

vector<pair<int,int> >GV[10001];
priority_queue<node>Q;

int dist[10001],n;
bool visited[10001];

void dij(int m){
	for (int i=1;i<=n;i++)
		dist[i]=INF;
	
	dist[m]=0;Q.push(node(0,m));
	
	while (!Q.empty()){
		node temp=Q.top();Q.pop();
		
		if (visited[temp.pos]) continue;
		
		int pos=temp.pos,data=temp.data;
		
		for (int i=0;i<GV[pos].size();i++)
			if (data+GV[pos][i].second<dist[GV[pos][i].first]){
				dist[GV[pos][i].first]=data+GV[pos][i].second;
				Q.push(node(dist[GV[pos][i].first],GV[pos][i].first));
			}
		
		visited[pos]=true;
	}
}

int main(){
	int v,m,x,y,data;
	
	cin>>n>>v>>m;
	
	for (int i=1;i<=v;i++){
		cin>>x>>y>>data;
		GV[x].push_back(make_pair(y,data));
	}
	
	dij(m);
	
	for (int i=1;i<=n;i++)
		cout<<dist[i]<<' ';
	
	cout<<endl;
	
	return 0;
}

谢谢观看。

 

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/Njhemu/article/details/80300446
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞