850. Dijkstra求最短路 II

dijkstra算法的堆优化版本,把找dist数组中的最小值的复杂度优化为O(1).

#include<iostream>
#include<cstring>

using namespace std;

const int N = 150010;

int heap[N], heap_node[N], ss = 1;
int dist[N];
int h[N], e[N], w[N], ne[N], idx;
int st[N];
int n, m;

void heap_swap(int a, int b){
    swap(heap[a], heap[b]);
    swap(heap_node[a], heap_node[b]);
}

void up(int x){
    while(x / 2 && heap[x] < heap[x / 2]){
        heap_swap(x, x / 2);
        x /= 2;
    }
}

void down(int x){
    int t = x;
    if(x * 2 <= ss && heap[x * 2] < heap[t]) t = x * 2;
    if(x * 2 + 1 <= ss && heap[x * 2 + 1] < heap[t]) t = x * 2 + 1;
    
    if(t != x){
        heap_swap(x, t);
        down(t);
    }
}

int dijkstra(){
    dist[1] = 0;
    heap_node[ss] = 1;
    heap[ss] = 0;
    
    while(ss){
        int k = heap_node[1];
        heap_swap(1, ss --);
        
        down(1);
        
        if(st[k]) continue; // 注意同一个结点可能在堆中存在多个不同距离的记录,所以此处用st来保证时间复杂度,这里不写这个判断也是对的,但是无法保证时间复杂度
        
        st[k] = 1;
        for(int i = h[k]; ~ i; i = ne[i]){
            int j = e[i];
            if(dist[j] > dist[k] + w[i]){
                dist[j] = dist[k] + w[i];
                ++ ss;
                heap_node[ss] = j;
                heap[ss] = dist[j];
                
                up(ss);
            }
        }
    }
    
    if(dist[n] == 0x3f3f3f3f) return -1;
    
    return dist[n];
}

void add(int a, int b, int x){
    e[idx] = b, w[idx] = x, ne[idx] = h[a], h[a] = idx ++;
}

int main(){
    memset(h, -1, sizeof h);
    memset(dist, 0x3f, sizeof dist);
    
    cin >> n >> m;
    
    while(m --){
        int a, b, w;
        
        cin >> a >> b >> w;
        add(a, b, w);
    }
    
    cout << dijkstra() << endl;
    
    return 0;
}
posted @ 2020-08-31 12:10  yys_c  阅读(104)  评论(0编辑  收藏  举报