Ну, как уже сказал Даррен, std::priority_queue
не имеет средств для уменьшения приоритета элемента и удаления элемента, отличного от текущего минимума. Но значение по умолчанию std::priority_queue
является не чем иным, как простым контейнерным адаптером вокруг std::vector
, который использует функции кучи std из <algorithm>
(std::push_heap
, std::pop_heap
и std::make_heap
). Поэтому для Дейкстры (где вам нужно обновить приоритет) я обычно делаю это сам и использую простой std::vector
.
Тогда толчок - это просто операция O (log N)
vec.push_back(item);
std::push_heap(vec.begin(), vec.end());
Конечно, для построения очереди заново из N элементов, мы не выталкиваем их всех, используя эту операцию O (log N) (делая все это O (Nlog N)), а просто помещаем их все в вектор, а затем простой O (N)
std::make_heap(vec.begin(), vec.end());
Элемент min является простым O (1)
vec.front();
Pop - это простая O (log N) последовательность
std::pop_heap(vec.begin(), vec.end());
vec.pop_back();
Пока это именно то, что std::priority_queue
обычно делает под капотом. Теперь, чтобы изменить приоритет элемента, нам просто нужно изменить его (однако он может быть включен в тип элемента) и снова сделать последовательность допустимой кучей
std::make_heap(vec.begin(), vec.end());
Я знаю, что это операция O (N), но, с другой стороны, это устраняет необходимость отслеживать положение элемента в куче с помощью дополнительной структуры данных или (что еще хуже) увеличения типа элементов , И снижение производительности по сравнению с обновлением логарифмического приоритета на практике не так уж важно, учитывая простоту использования, компактное и линейное использование памяти std::vector
(что также влияет на время выполнения), а также тот факт, что я часто работаю с графиками, которые имеют в любом случае, довольно мало ребер (линейных по числу вершин).
Это не во всех случаях может быть самый быстрый способ, но, безусловно, самый простой.
РЕДАКТИРОВАТЬ: О, и поскольку стандартная библиотека использует max-heaps, вам нужно использовать эквивалент >
для сравнения приоритетов (однако вы получаете их из элементов), вместо значения по умолчанию <
оператор.