DJ 算法的队列优先优化

DJ算法就是求单源最短路的算法,但是时间复杂度不太理想,所以在此献上用最小堆来优化的算法。

如果不懂优先队列可以先去看STL分类关于优先队列的介绍;

///POJ 2387为例
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int maxn = 1e3 + 50;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> HeapNode;///在堆里面的是pair、first为到起点距离、second为点编号
struct EDGE{ int v, nxt, w; };

int Head[maxn], Dis[maxn];
EDGE Edge[maxn*100];
int N, M, cnt;

inline void init()
{
    for(int i=0; i<=N; i++)
        Head[i]=-1, Dis[i]=INF;
    cnt = 0;
}

inline void AddEdge(int from, int to, int weight)
{
    Edge[cnt].w = weight;
    Edge[cnt].v = to;
    Edge[cnt].nxt = Head[from];
    Head[from] = cnt++;
}

int Dijkstra()
{
    priority_queue<HeapNode, vector<HeapNode>, greater<HeapNode> > Heap;
    Dis[1] = 0;
    Heap.push(make_pair(0, 1));
    while(!Heap.empty()){
        pair<int, int> T = Heap.top(); Heap.pop();
        if(T.first != Dis[T.second]) continue;///有很多版本都是用 vis 标记是否已经使用这个点松弛过、这里可以用这个不同的方法!
        
        for(int i=Head[T.second]; i!=-1; i=Edge[i].nxt){
            int Eiv = Edge[i].v;
            if(Dis[Eiv] > Dis[T.second] + Edge[i].w){
                Dis[Eiv] = Dis[T.second] + Edge[i].w;
                Heap.push(make_pair(Dis[Eiv], Eiv));
            }
        }
    }
    return Dis[N];
}

int main(void)
{
    while(~scanf("%d %d", &M, &N)){

        init();

        int from, to, weight;
        for(int i=0; i<M; i++){
            scanf("%d %d %d", &from, &to, &weight);
            AddEdge(from, to, weight);
            AddEdge(to, from, weight);
        }

        printf("%d\n", Dijkstra());
    }
    return 0;
}
View Code

 

该算法实现了1到各个点的最短距离;

posted @ 2018-04-30 13:31  shuai_hui  阅读(365)  评论(0编辑  收藏  举报