常用图论算法模板(1)dijkstra算法求最短路

dijkstra算法主要用于求解图论算法中任意两点间的最短路问题,该算法维护了一个dist数组,代表了每个点距离起点的距离,在开始时,dist数组中的元素应当全部为正无穷,且起点在dist数组中的值为0。该算法每次从距离起点距离未确定的点中找出一个距离起点最近的点,将其确定下来,并用该点距离起点的距离更新图中其他点与起点的最短距离。
注意: 当图中存在负权边时dijkstra算法无法保证正确性
dijkstra算法存在两种版本

普通版dijkstra

该版本每次在寻找距离起点最近的未确定的点时采用循环遍历整个数组的方式,时间复杂度为 O ( n 2 ) O{(n^2)} O(n2) 在稠密图中或者题目使用邻接矩阵时更加适用。
代码模板

int dijkstra(int start, int end)
{
    memset(dist, 0x3f, sizeof dist);
    dist[start] = 0;
    for(int i = 1; i <= n; i ++ ) {
        int t = -1;
        for(int j = 1; j <= n; j ++ ) 
            if(!st[j] && (dist[j] < dist[t] || t == -1))
                t = j;
        st[t] = true;
        for(int j = 1; j <= n; j ++ )
            dist[j] = min(dist[j], dist[t] + g[t][j]);
    }
    return dist[end];
}

堆优化版dijkstra

该版本采取将所有被更新过的点及其距离放入优先队列的策略,将确定最近未确定点的时间复杂度由 O ( n ) O(n) O(n) 降低到了 O ( l o g n ) O(logn) O(logn) ,优先队列调整 O ( l o g n ) O(logn) O(logn),取最小 O ( 1 ) O(1) O(1) ,更适合稀疏图,以及邻接表存图使用。
代码模板

int dijkstra(int Ts, int Te)
{
    memset(dist, 0x3f, sizeof(dist));
    dist[Ts] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>q;
    q.push({0, Ts});
    while(!q.empty()){
        int u = q.top().second;
        q.pop();

        for(int i = h[u]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(dist[j] > dist[u] + w[i]) {
                dist[j] = dist[u] + w[i];
                q.push({dist[j], j});
            }
        }
    }
    return dist[Te];
}

不难发现两种做法的区别在于从剩余点中取出最近点的策略,在实际做题中,题目大多给出两个点及其权值,使得第二种方法的使用更加普遍。

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值