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; }
该算法实现了1到各个点的最短距离;