c++ - 使用给定路径查找 MST (C++)
问题描述
我有一个用于查找 MST 的代码,其中包括一个给定的 MST 路径,它给了我正确的 MST 权重(我知道输出应该是什么)。我试图重写代码的一部分以使用std::map
而不是std::vector
进行更有效的查找(从下面的代码中可以清楚地看出),但现在它给出了错误的答案,尽管研究了几个小时,我还是无法理解我在哪里做错了。任何有关定位错误的帮助将不胜感激。
旧版本使用vector<Edge>
. 遍历所有边的向量 ( m_all_edges
)。如果边e
在 中vector<Edge> path
,则将其添加到 MST ( m_mst
)。m_edges
否则,将其添加到 MST ( )的候选边。
void MSTPath::m_add_shortest_path_old(vector<Edge> path){
for (auto e : path){
m_graph->union_vu(e.get_node(),e.get_opposite_node(-1));
}
for (auto e : m_all_edges){
if (tempfunc(e,path)) m_mst.push_back(e);
else m_edges.push_back(e);
}
}
bool MSTPath::tempfunc(Edge e, vector<Edge> path){
for (auto edge : path){
if((edge.get_node()==e.get_node())&&(edge.get_opposite_node(-1)==e.get_opposite_node(-1))) return true;
}
return false;
}
版本与std::map
.
void MSTPath::m_add_shortest_path(map<Edge,int> path_map){
for (auto const& x : path_map){
Edge e = x.first;
m_graph->union_vu(e.get_node(),e.get_opposite_node(-1));
}
for (auto const& x : m_all_edges_map){
if ((path_map.count(x.first)>0)||(path_map.count(x.first.reversed())>0)) m_mst.push_back(x.first);
else m_edges.push_back(x.first);
}
}
查找 MST 的函数(在调用m_add_shortest_path
/之后调用m_add_shortest_path_old
)。
int MSTPath::m_compute_mst(){
sort(m_edges.begin(),m_edges.end(),[](Edge e1, Edge e2) { return e1.weight < e2.weight; });
int i = 0;
int mst_size = m_mst.size();
int mst_weight = 0;
int v,u;
for (Edge e : m_mst) mst_weight += e.weight;
while (mst_size<m_N-1){
Edge edge = m_edges[i++];
v = m_graph->find(edge.get_node());
u = m_graph->find(edge.get_opposite_node(-1));
if (u!=v){
mst_size++;
mst_weight += edge.weight;
if (mst_weight>=min_mst_weight) return numeric_limits<int>::max();
m_mst.push_back(edge);
m_graph->union_vu(v,u);
}
}
return mst_weight;
}
据我所知,这两个函数都完全相同m_mst
(并且开始mst_weight
)和相同m_edges
(但顺序不同)。但是排序对算法来说应该不是问题(除了按重量排序,但这是句柄m_compute_mst
),对吧?
Edge
班级:
class Edge{
public:
Edge(int v_e, int u_e, int w){
v = v_e;
u = u_e;
weight = w;
}
int get_node() const { return v; }
int get_opposite_node(int k) const {
if ((k==v) || (k==-1)) return u;
else return v;
}
Edge reversed() const {
return Edge(u,v,weight);
}
bool operator<(const Edge& e) const {
if (this->get_node()<e.get_node()) return true;
else if (this->get_node()==e.get_node()) return this->get_opposite_node(-1)<e.get_opposite_node(-1);
else return false;
}
int v, u, weight;
};
是的,我知道按值传递会产生额外的副本。这是一个临时版本。
解决方案
推荐阅读
- python - Pandas groupby and then pivot is not returning the desired output
- javascript - 深度反应useEffect / useEffect的使用?
- php - 第一次重新加载后的空会话变量
- python - Pyinstaller 创建 Pyside2 脚本的 exe 文件
- flutter - 如何在颤动中将主题存储在共享首选项中
- node.js - 如何使用 Node.js 快速会话处理唯一会话(一个用户会话)?
- javascript - 保存到 LocalStorage 数组未正确更新 React
- javascript - 如何在不破坏使用 redux Connect 的应用程序的情况下异步加载 redux 存储?
- node.js - 有没有办法在公共文件夹中安装 css bootstrap 而不是默认安装 node-module 文件夹?
- postgresql - 如何使用 GIST 结合布尔值在 lat/lon col 上创建索引?