堆优化的dijkstra(手写堆)

利用小根堆优化每次查找dis数组最短距离的复杂度

只要看过小根堆,这个代码并不难,但有细节需要处理

我是手写堆,但用priority_queue更简单

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000;
int f[maxn][maxn];
int vis[maxn];
int d[maxn];
const int inf=999999;
int len;
struct dot{
	int xu;
	int va;
}dis[maxn];//设置结构体,保存节点的序号和值 
//手写堆的push操作 
void push(dot n){ 
	dis[++len]=n;
	int son=len;
	while(son/2){
		if(dis[son/2].va>dis[son].va){
			swap(dis[son/2],dis[son]);
		    son/=2;
		}
		else break;
	}
}
//pop操作 
dot pop(){
	dot tp=dis[1];
	swap(dis[1],dis[len--]);
	int pa=1,son=2;
	while(son<=len){
		if(dis[son].va>dis[son+1].va&&son<len){
			son++;//别忘了判断son+1是否超过len 
		}
		if(dis[son].va>dis[pa].va)
		   break;
		 swap(dis[son],dis[pa]);
		 pa=son;
		 son=pa*2;
	}
	return tp;
}
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		f[x][y]=f[y][x]=z;
	}
	fill(d,d+maxn,inf);
	push({1,0});
	d[1]=0;
	while(len){
		dot tp=pop();
		if(vis[tp.xu])//由于一个点的最短距离会多次改变,
		//所以堆中可能会有多个重复节点 ,但每次取出的是最小的,所以被取出一次后,
		//后面的重复节点都可以忽略 
		 continue;
		vis[tp.xu]=1;
		for(int i=1;i<=n;i++){
		   if(f[tp.xu][i]&&!vis[i]&&d[i]>f[tp.xu][i]+tp.va)
		   {
		   	push({i,f[tp.xu][i]+tp.va});
		   	d[i]=f[tp.xu][i]+tp.va;//d的值不要忘了改 
		   }
		}
	}
	cout<<d[n];
	return 0;
} 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值