Алгоритм Крускала STL

На основе видео я написал алгоритм Крускала. Но у меня есть «маленькая» проблема — вместо того, чтобы находить самые низкие веса, она находит меня самой высокой. Это может звучать смешно, но я не могу найти, где я допустил ошибку.

collection::collection(int vert){ coll = new SNode[vert]; }
collection::~collection(){}
void collection::Create(int vert)
{
coll[vert].up = vert;
coll[vert].rank = 0;
}
int collection::Find(int vert)
{
/*if (coll[vert].up != vert) coll[vert].up = Find(coll[vert].up);
return coll[vert].up;*/
if (coll[vert].up == vert) return coll[vert].up;
else Find(coll[vert].up);
}
void collection::Union(graf::Edges e)
{
int home, dest;
home = Find(e.v1);
dest = Find(e.v2);
if (home != dest){
if (coll[home].rank > coll[dest].rank){ coll[dest].up = home; }
else if (coll[home].rank < coll[dest].rank){ coll[home].up = dest; }
else{
coll[home].up = dest;
//if (coll[home].rank == coll[dest].rank)
coll[dest].rank++;
}
}
}

И основной алгоритм. Веса хранятся в двухмерной матрице, называемой ‘weightmat’. Vertex — это количество вершин, Edges — структура с переменными v1, v2, weight. Используя эту структуру, я создаю массив ребер. :

collection newcollection(vertex);

struct CompareMat{
bool operator()(Edges &node1, Edges &node2){
if (node1.weight < node2.weight) return true;
else return false;
}
};

priority_queue<Edges, vector<Edges>, CompareMat> EdgesQueue;
Edges temp;
Edges* edges = new Edges[edge];
Edges* MSTTree = new Edges[vertex-1];

for (int i = 0; i < vertex; i++){
for (int j = 0; j < vertex; j++)
{
if (nbhmat[i][j] != 0){
edges[i].v1 = i;
edges[i].v2 = j;
edges[i].weight = weightmat[i][j];
}
}
EdgesQueue.push(edges[i]);
}

for (int i = 0; i < vertex; i++){
newcollection.Create(i);
}

for (int i = 1; i < vertex; i++)
{
do
{
temp = EdgesQueue.top();
EdgesQueue.pop();
} while (newcollection.Find(temp.v1) == newcollection.Find(temp.v2));
MSTTree[i - 1] = temp;
newcollection.Union(temp);
}

cout << endl << endl << "Kruskal's algorithm for matrix:" << endl;
for (int i = 0; i < vertex - 1; i++){
cout << MSTTree[i].v1 << " " << MSTTree[i].v2 << " weight " << MSTTree[i].weight << endl;
}

-1

Решение

priority_queue имеет самый большой элемент на его вершине (да, с классом компаратора, эквивалентным less), но сначала вам нужны самые маленькие края. Вы должны инвертировать свой CompareMat::operator() сравнение.

Еще две заметки.

Во-первых, в CompareMat::operator() Вы можете вернуть результат сравнения напрямую:

//return node1.weight < node2.weight; // your version
return node1.weight > node2.weight;  // correct version

Во-вторых, зачем вам приоритетная очередь? Достаточно простой сортировки, потому что вы, кажется, не меняете свои края.

2

Другие решения


По вопросам рекламы [email protected]