又敲了一遍堆,有了更深的理解。
插入操作:在數組尾部加入元素,自動上浮。
刪除操作:將數組尾部元素提到根節點,向小的子節點下沉。
印象中優先隊列會是指標+繁瑣操作的,實則代碼可以簡化到6行內。
只比SPFA是稍遜一點,rank2的最短路演算法。
#include <stdio.h><br />#include <stdlib.h><br />#include <vector><br />using namespace std;<br />const int MaxN = 10001;<br />const int INF = 0x7fffffff/2 - 1;<br />typedef struct {int dis , vex;} ElemType;<br />typedef struct {int vex , dis;}Edge;<br />typedef vector < Edge > VE;<br />VE edge[MaxN];<br />bool cmp(ElemType e1 , ElemType e2)<br />{<br />return e1.dis < e2.dis;<br />}<br />class Heap<br />{<br />public:<br />Heap(){n = 0;}<br />int min(int _a , int _b){<br />return a[_a].dis < a[_b].dis ? _a : _b;<br />}<br />void push(ElemType e){<br />for (i = ++ n;i > 1 && cmp(e , a[i >> 1]);i >>= 1){<br />a[i] = a[i >> 1];<br />}<br />a[i] = e;<br />}<br />void pop(){<br />ElemType e = a[n];<br />for (i = 2;i < n;i <<= 1){<br />if (i < n - 1){<br />i = min(i , i + 1);<br />}<br />if (cmp(e , a[i])) break;<br />a[i >> 1] = a[i];<br />}<br />a[i >> 1] = a[n --];<br />}<br />ElemType top(){<br />return a[1];<br />}<br />bool empty(){<br />return !n;<br />}<br />private:<br />ElemType a[MaxN];<br />int n , i;<br />};<br />void dijkstra(int nvex , int st)<br />{<br />Heap h;<br />Edge e;<br />ElemType tmp;<br />int dis[ MaxN ] , i , now;<br />bool visited[ MaxN ] = {0};</p><p>tmp.dis = 0;<br />tmp.vex = st;<br />h.push(tmp);<br />for (i = 0;i < nvex;i ++)dis[ i ] = INF;<br />dis[ st ] = 0;<br />while (!h.empty()){<br />tmp = h.top();h.pop();<br />now = tmp.vex;<br />if (!visited[ now ]){<br />visited[ now ] = true;<br />for (i = 0;i < (int)edge[ now ].size();i ++){<br />e = edge[ now ][ i ];<br />if (!visited[ e.vex ] && dis[ now ] + e.dis < dis[ e.vex ]){<br />tmp.dis = dis[ tmp.vex = e.vex ] = dis[ now ] + e.dis;<br />h.push(tmp);<br />}<br />}<br />}<br />}<br />for (i = 0;i < nvex;i ++){<br />if (dis[ i ] == INF){<br />printf("-1 ");<br />}else{<br />printf("%d " , dis[ i ]);<br />}<br />}<br />}<br />void __test()<br />{<br />Edge e;<br />int n , m , i , a , b , c;</p><p>scanf("%d%d" , &n , &m);<br />for (i = 0;i < n;i ++){<br />edge[i].clear();<br />}<br />for (i = 0;i < m;i ++){<br />scanf("%d%d%d" , &a , &b , &e.dis);<br />e.vex = b;edge[a].push_back(e);<br />e.vex = a;edge[b].push_back(e);<br />}<br />scanf("%d" , &a);<br />dijkstra(n , a);<br />}<br />int main()<br />{<br />__test();<br />}<br />/*<br />8 9<br />0 1 5<br />1 2 8<br />1 3 7<br />1 5 4<br />4 5 6<br />5 6 7<br />6 7 3<br />1 7 2<br />1 6 1<br />2<br />3 3<br />0 1 5<br />0 2 1<br />1 2 3<br />0<br />4 5<br />0 1 1<br />0 2 2<br />0 3 5<br />1 2 1<br />1 3 2<br />*/