这是克鲁斯卡尔算法的正确实现吗?
Is this a proper implementation of Kruskal's algorithm?
我编写了以下代码作为UVA OnlineJudge问题#10034的解决方案:
// problem 10034
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
class tree;
class vertex {
public:
double x,y;
tree* mTree;
};
class tree {
public:
tree(tree* last,vertex* v);
int size();
void assimilate(tree* other);
tree* prev;
tree* next;
vector<vertex*> vertices;
};
tree::tree(tree* last,vertex* v) {
prev = last;
next = NULL;
vertices.push_back(v);
v->mTree = this;
if(last != NULL) {
last->next = this;
}
}
int tree::size() {
return vertices.size();
}
void tree::assimilate(tree* other) {
int c;
if(other->prev != NULL) {
other->prev->next = other->next;
}
if(other->next != NULL) {
other->next->prev = other->prev;
}
for(c = 0;c < other->vertices.size();c++) {
this->vertices.push_back(other->vertices[c]);
other->vertices[c]->mTree = this;
}
delete other;
}
class edge {
public:
edge() {
v1 = NULL;
v2 = NULL;
weight = 0;
}
edge(vertex* a,vertex* b,double w) {
v1 = a;
v2 = b;
weight = w;
}
bool operator<(const edge& rhs) const {
return this->weight < rhs.weight;
}
vertex* v1;
vertex* v2;
double weight;
};
double dist(double x1,double y1,double x2,double y2) {
double dx;
double dy;
dx = x2 - x1;
dy = y2 - y1;
return sqrt((dx*dx) + (dy*dy));
}
int main() {
int ncases;
int ccase;
int c;
int nverts;
int nedges;
edge* edges;
vertex* vertices;
tree* lasttree;
double cost;
tree* t1;
tree* t2;
bool treeexists;
int cedge;
int cc;
cin>>ncases;
for(ccase = 0;ccase < ncases;ccase++) {
cin>>nverts;
nedges = (nverts*(nverts-1)) / 2;
treeexists = false;
lasttree = NULL;
vertices = new vertex[nverts];
edges = new edge[nedges];
cedge = 0;
for(c = 0;c < nverts;c++) {
cin>>vertices[c].x;
cin>>vertices[c].y;
lasttree = new tree(lasttree,&vertices[c]);
}
for(c = 0;c < nverts;c++) {
for(cc = c+1;cc < nverts;cc++) {
edges[cedge] = edge(vertices+c,vertices+cc,dist(vertices[c].x,vertices[c].y,vertices[cc].x,vertices[cc].y));
cedge++;
}
}
sort(edges,edges+nedges);
cost = 0;
for(c = 0;c < nedges;c++) {
//cout<<"edge with length "<<edges[c].weight<<endl;
if(edges[c].v1->mTree != edges[c].v2->mTree) {
//cout<<"using"<<endl;
cost += edges[c].weight;
t1 = edges[c].v1->mTree;
t2 = edges[c].v2->mTree;
if(t1->size() > t2->size()) {
t1->assimilate(t2);
} else {
t2->assimilate(t1);
}
}
}
if(ccase > 0) {
cout<<endl;
}
cout<<fixed<<setprecision(2)<<cost;
delete vertices[0].mTree;
delete[] vertices;
delete[] edges;
}
return 0;
}
它适用于问题提供的测试用例和我在这里找到的更大的测试用例:http://online-judge.uva.es/board/viewtopic.php?p=21939#p21939
但是,当我将其提交给UVA时,我收到错误的答案消息。我对 Krukar 算法的实现是否正确?我做错了什么?
首先,为什么不使用联合查找数据结构而不是对指针结构进行复杂的操作?
其次,这个问题似乎有一个令人讨厌的把戏。 您不仅需要最小生成树。 考虑一下案例
4
0.0 0.0
1.0 0.0
1.0 1.0
0.0 1.0
我只需要 2 sqrt(2) 个墨水单位来连接所有点;我使 X 成为两行长度为 sqrt(2) 的行。 但是,最小生成树的长度为 3。
相关文章:
- std::unordered_map 搜索算法是如何实现的?
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 了解算法的性能差异(如果以不同的编程语言实现)
- 它是否定义了哪些算法可以接受可变 lambda 的实现?
- 为什么在此排序算法实现中,向量明显比数组慢?
- 快速实现 PRIM 算法
- 如何知道用于实现标准代码段的确切数据结构和算法,例如在C++STL中?
- 在 Eigen3 中实现 Bartels-Stewart 算法 -- 仅实矩阵?
- 在 c++ 或 python 中生成一个体面的视差图以在 Raspberry Pi 上实现的最佳方法(算法或函数)是什么
- 字母C++实现中的 Prim 算法
- 尝试实现二叉搜索算法,似乎无法使其工作
- C++17 并行算法已经实现了吗?
- AES_XCBC算法的实现
- C++ GDAL 算法 GDALFillNodata() 的实现
- 如何检查 CNG Windows API 是否返回符合 FIPS 的算法实现
- OpenMP:共享同一算法的单线程和多线程实现
- 使用L1CPUCache实现c++算法的Python
- 实现算法(气泡排序)来组织阵列
- 实现O(n)算法来确定字符串是否所有字符都是唯一的
- 我应该如何去实现算法与黑白和彩色图像使用