[英]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時,會收到錯誤的答復消息。 我對Krukal算法的實現正確嗎? 我究竟做錯了什么?
首先,為什么不使用聯合查找數據結構而不是對指針結構進行復雜的操作?
第二,這個問題似乎有一個討厭的竅門。 您不只是想要最小的生成樹。 考慮一下情況
4
0.0 0.0
1.0 0.0
1.0 1.0
0.0 1.0
我只需要2 sqrt(2)單位墨水即可連接所有點; 我將兩行長度為sqrt(2)的X設為X。 但是,最小生成樹的長度為3。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.