I want to use priority_queue as vertex container for a dikjstra algorithm, after calling extractMin
to get a vertex u
, I find all adjacent vertex v
, and then I might call decreaseKey
for v
, I known that the decreaseKey
spend O(lgN) time, however, before calling decreaseKey
, I have to first find the position of v
.
I used std::vector
and std::make_heap/std::push_heap/std::pop_heap
to maintain the priority_queue, using this data structure, to find a specific data would spend O(N) time, which would make the O(lgN) decreaseKey
meaningless.
So, what is the common method for the vertex container in dikjstra algorithm, or should I add a member in class Vertex
to keep its position in the heap?
First of all you do not need to use std::***_heap
functions; There already is priority_queue
in STL.
As for updating values already in the heap, you may insert pair
s of index and distance. And maintain a distance vector to verify if the distance is still valid or has got updated; something like:
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);
Then the Dikjstra loop would be something like:
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 */
}
It is true that there may be multiple copies of a same node in the heap (at different distances where only one of them is still valid); but you may show that the size of the heap is O(num. of edges)
, therfore the heap would still perform O(log num. of nodes)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.