堆优化版Dijkstra算法思路

注意:Dijkstra算法只适用于边权为非负值的带权图

时间复杂度为O(m*log n)级别

主要思路:(采用STL中的优先队列进行优化)

准备工作:先用vector容器开适当大小的数组存放与每个点相连点的位置与边权(用pair类型成对存放),创建dis[N]来存放所有点到起始点的距离,并将所有点到起始点的距离初始化为INF(int范围内最大的数),以便后续更新最短距离。创建vis[N]来标记某个点是否被更新过。

将某点的编号和该点当前到起始点最短距离存入队列(假设点1为起始点,点1到1的最短距离为0,那么将存入(1,0)),当队列不为空时选出堆顶元素(以下操作一直循环到队列为空),用该点(假设为点u)的位置带入vector容器遍历与点u相连的点(假设为点v),如果dis[v]>dis[u]+边u-v的边权(用w表示),就将dis[v]更新为dis[u]+w;最后再把(v,dis[v])存入队列即可。

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
const int INF=1e9;
int dis[N];
bool vis[N];
vector <pair<int,int> >g[N];
struct note{
	int id;//点的位置
	int d;//该点到起始点的最短距离
};
bool operator<(note a,note b){//重载小于号运算符,让堆元素从小到大排列
	return a.d>b.d; 
}
priority_queue<note> que;
int n,m,u,v,w;

Dijkstra(int st){
	for(int i=1;i<=n;i++){
	    vis[i]=0,dis[i]=INF;//初始化
	} 
	dis[st]=0;
	que.push({st,0});
	while(!que.empty()){
		note t=que.top();que.pop();//每次取出堆顶元素后弹出该元素
		int u=t.id;
		if(vis[u]) continue;//如果已经被更新过就跳过该点
		vis[u]=1;
		for(auto eg:g[u]){//遍历与点u相邻的所有点
			int v=eg.first;
			int w=eg.second;
			if(dis[v]>dis[u]+w) dis[v]=dis[u]+w;
			que.push({v,dis[v]});
		}
	}
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		g[u].push_back({v,w});
	}
	int st;cin>>st;
    Dijkstra(st);
    for(int i=1;i<=n;i++){
    	cout<<st<<"->"<<i<<" shortest path is"<<dis[i]<<endl;
	}
    return 0;
}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值