Dijkstra算法求最短路(堆优化版)

堆优化版Dijkstra求最短路

思路:上一篇博客介绍的方法每次要找出最小值来更新下一次,而我们可以将每次更新的值直接放到升序的优化队列当中去,就可以少一个循环,将这一步的时间复杂度优化到O(1)。

建议结合上一篇博客一起看,理解这两个方法到底有什么本质的不同。

上代码:

#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include <algorithm>
using namespace std;
typedef pair<int,int>PII;
const int N = 1e6 + 10 , M = 2 * N;
priority_queue<PII,vector<PII>,greater<PII> > heap;
int h[N] , e[M] , w[N] , ne[M] , idx;
int dist[N];
bool st[N];
int n,m;

void add(int a, int b, int c)//稠密图用邻接表来存储图。
{
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx ++;
}

int Dijstra()
{
    
    dist[1] = 0;//首先更新起点到起点的距离为0。
    
    heap.push({0,1});//将这个点放到优化队列中去。第一个点代表距离,第二个点代表数字编号。
    
    while(!heap.empty())
    {
        PII t = heap.top();//取出对队头。(升序排列优化队列队头就是最小值)
        heap.pop();//将队头删掉
        if(st[t.second]) continue;//判断如果这个点已经确定最小值了,就直接跳过这个点。
        for(int i = h[t.second] ; i != -1 ; i = ne[i])
        {
            int j = e[i];
            
            if(dist[j] > dist[t.second] + w[i])//比较现在准备更新的这个点和上一次更新的点那个小。
            {
                dist[j] = dist[t.second] + w[i];//每次将较小的值更新,如果比上次大就不更新。
                heap.push({dist[j] , j});//将每次更新的每个点放到优化队列中去。
            }
        }
            
        st[t.second] = true;//标记这个点已经确定最小值。
    }
    
    if(dist[n] == 0x3f3f3f3f) return -1;//如果要求的点一直没有更新,说明走不到这个点。
    return dist[n];//否则返回该点最后更新到的距离即为该点到起点的最短距离。
}

int main()
{
    cin>>n>>m;
    
    memset(h,-1,sizeof h);
    memset(dist,0x3f,sizeof dist);
    
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
    }
    
    cout<<Dijstra()<<endl;
    
    return 0;
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值