I'm implementing Kruskal's algorithm, which is a well-known approach to finding the minimum spanning tree of a weighted graph. However, I am adapting it to find cycles in a graph. This is the pseudocode for Kruskal's algorithm:
KRUSKAL(G):
1 A = ∅
2 foreach v ∈ G.V:
3 MAKE-SET(v)
4 foreach (u, v) ordered by weight(u, v), increasing:
5 if FIND-SET(u) ≠ FIND-SET(v):
6 A = A ∪ {(u, v)}
7 UNION(u, v)
8 return A
I'm having a hard time grasping the FIND-SET()
and MAKE-SET()
functions, or their implementation with the disjoint-set data structure.
My current code looks like this:
class edge {
public: //for quick access (temp)
char leftV;
char rightV;
int weight;
};
std::vector<edge> kruskalMST(std::vector<edge> edgeList){
std::vector<char> set;
std::vector<edge> result;
sortList(edgeList); //sorts according to weight ( passed by reference)
do{
if(set.empty()){
set.push_pack(edgeList[i].leftV); //also only push them when
set.push_pack(edgeList[i].rightV); //they aren't there , will fix
result.push_back(edgeList[i]);
++i;
}
else {
if((setContains(set , edgeList[i].leftV)) && (setContains(set , edgeList[i].rightV)))
++i; //skip node
else {
set.push_pack(edgeList[i].leftV); //also only push them when
set.push_pack(edgeList[i].rightV); //they aren't there , will fix
result.push_back(edgeList[i]);
++i;
}
} while(i<edgeList.size());
return result;
}
My code detects a cycle in a graph when two vertices which are already present in set vector
appear again. This seemed to work in most cases until I encountered a situation like this:
[a] [c]
| |
| |
| |
[b] [d]
When these edges appear in sorting order, this happens because a
, b
, c
, d
have already been pushed into set vector
. Joining [a]
to [c]
doesn't produce a cycle inside the graph but is detected as a cycle due to current implementation.
Is there any viable alternative to detect cycles in my case? Or if someone could explain how MAKE-SET
, FIND-SET
, and UNION
work in Kruskal's algorithm, that would help a lot.