优先队列和Prim算法

时间:2014-01-09 14:01:04

标签: c++ algorithm stl

我已经阅读了C ++参考手册,目前还不清楚如何在STL中使用priorityqueue数据结构。

所以,基本上我一直在尝试使用堆来实现自己。

我这样做是为了实现Prim的算法。

Vector <int, int> pq;

这是我的优先级队列。第一个字段是节点,第二个字段是现有树的权重。

每次通过更新其邻居节点的权重将新节点添加到树中时,我计划修改pq中的权重值。

  • 如何访问此向量的各个元素?我还需要能够随意删除元素。

这是实现优先级队列的好方法吗?如果我想在容器中添加另一个字段,即

,该怎么办?
Vector<int, int, int> MST
  • 我如何访问第三个元素?我希望以这种方式存储生成的MST,使得前两个字段表示形成边缘的顶点,第三个字段表示权重。

如果有人可以告诉我如何使用push_back为此向量分配元素,这也会有所帮助。

  • 此外,传统的C ++ STL优先级队列是否有助于此,因为每次将新元素添加到MST时我都需要更新优先级值?当值被修改时,它会根据优先级自我纠正吗?

  • 另外一个问题,这些向量,当我将它们传递给函数并尝试进行更改时,它是值传递还是按引用传递 - 或者,更改是否反映在函数外部?

2 个答案:

答案 0 :(得分:5)

在Prim的算法中,随机访问不需要的元素。您只需要跳过连接已连接并向前传递的队列中的元素。

所以算法如下:

  1. 选择节点N
  2. N的所有边添加到PQ
  3. 从PQ中获得最低成本优势
    • 如果它连接已经在树中的节点,则跳过它
    • 否则将此边添加到树中,调用新节点N并返回到第2点。
  4. 添加节点后,只需检查树的大小是否已size of graph - 1。如果是,那就完成。

    请注意,PQ上的唯一操作是add_elementpop_minimum - 因此std::priority_queue将起作用。

答案 1 :(得分:2)

首先,std::vector<int,int>无效 - 第二个类型参数是(可选)分配器,而int不是分配器。如果您使用的是不同的底层容器,请说明它是什么。我假设您现在想要使用std::vector

其次,std::priority_queue不支持您想要的操作(访问和删除任意元素),因此您无法使用它。

您可以直接使用底层矢量,并使用堆算法(std::make_heap等)对其进行排序:

  • 随机访问将起作用(虽然一旦你的向量按堆顺序,你不希望索引是什么)
  • 删除任意元素将需要从向量中删除它并重新运行make_heap,或者您可以实现自己的 siftDown

哦,您可以在矢量中存储一些值类型,例如

std::vector<std::pair<int,int>>

第一个例子,或者更清楚:

struct {
  int node;
  int weight;
} Node;
// ...
std::vector<Node>