首先你不需要使用std::***_heap
函數; STL中已有priority_queue
。
至於更新已經在堆中的值,您可以插入pair
s的索引和距離。並保持距離矢量以驗證距離是否仍然有效或已更新;是這樣的:
typedef struct {
size_t index; /* index of vertex and the distance at which */
int dist; /* the vertex was pushed to the heap */
} value_t;
/* `a` has less priority than `b` if it is further away */
const auto comp = [](const value_t & a, const value_t & b){
return b.dist < a.dist;
};
priority_queue<value_t, vector<value_t>, decltype(comp)> heap(comp);
/* the *most current* shortest distances for all nodes */
vector<int> dist(n, inf);
然後Dikjstra循環將是這樣的:
while(!heap.empty()) {
const auto top = heap.top();
heap.pop();
if(dist[top.index] < top.dist) {
/* the node has already been added at a */
/* shorter distance therefore skip it */
continue;
}
/* process the node & its neighbors */
/* push to the heap neighbors which get their `dist` deccreased */
}
這是真的,有可能是在堆同一節點的多個副本(在不同的距離只有其中一個他們仍然有效);但是您可能會發現堆的大小爲O(num. of edges)
,因此堆仍然會執行O(log num. of nodes)
。
實際上這是我正在使用的方法,但是,一個節點可能會被推動很多次的事實使我有點討厭.... – Alaya