def is_forest(g): """ A forest is an acyclic, undirected graph. :param g: undirected graph :return: True if graph is a forest, otherwise False """ if not isinstance(g, Graph): return False djset = DisjointSet() for v in g.vertices: djset.make_set(v) eset = set() for v1, v2 in g.edges: if (v2, v1) not in eset: eset.add((v1, v2)) for v1, v2 in eset: if djset.find_set(v1) != djset.find_set(v2): djset.union(v1, v2) else: return False return True
def testUnionFind(self): ds = DisjointSet(range(100)) for i in range(100): ds.union(i, i % 5) for i in range(100): for j in range(i, 100): self.assertEqual( ds.find_set(i) == ds.find_set(j), i % 5 == j % 5)
def connected_components(self): "Returns a list of sets of connected components" ds = DisjointSet() for v in self.vertices(): ds.make_set(v) for u,v in self.edges(): if ds.find_set(u) != ds.find_set(v): ds.union(u,v) return ds.collection
def connected_components_dj(g): djset = DisjointSet() for v in g.vertices: djset.make_set(v) for v1, v2 in g.edges: if djset.find_set(v1) != djset.find_set(v2): djset.union(v1, v2) return djset.get_set()
def mst_kruskal(g): djset = DisjointSet() mst = Graph() for u in g.vertices: djset.make_set(u) for u, v in sorted(g.edges, key=lambda e: g.weight(e[0], e[1])): if djset.find_set(u) != djset.find_set(v): djset.union(u, v) mst.add_edge(u, v, g.weight(u, v)) return mst