class LazyPrimMST: # Compute a minimum spanning tree (or forest) of an edge-weighted graph. #the edge-weighted graph def __init__(self, G): self._mst = [] self._pq = MinPQ(G.V()) self._marked = [False] * G.V() self._weight = 0 for v in range(0, G.V()): if not self._marked[v]: self._prim(G, v) # run Prim's algorithm def _prim(self, G, s): self._scan(G, s) while not self._pq.isEmpty(): e = self._pq.del_min() v = e.either() w = e.other(v) assert (self._marked[v] or self._marked[w]) if (self._marked[v] and self._marked[w]): continue self._mst.append(e) self._weight += e.weight() if not self._marked[v]: self._scan(G, v) if not self._marked[w]: self._scan(G, w) # add all edges e incident to v onto pq if the other endpoint has not yet been scanned def _scan(self, G, v): assert not self._marked[v] self._marked[v] = True for e in G.adj(v): if not self._marked[e.other(v)]: self._pq.insert(e) def weight(self): return self._weight def edges(self): return self._mst
class LazyPrimMST(MST): """最小生成树的Prim算法的延时实现""" def __init__(self, G): self.pq = MinPQ() # 横切边(包括失效的边) self.marked = [False] * G.V() # 最小生成树的顶点 self.mst = [] # 最小生成树的边 self.visit(G, 0) # 假设G是联通的 while not self.pq.isEmpty(): # 遍历横切边 e = self.pq.delMin() # 取最小的边 v = e.either() w = e.other(v) if self.marked[v] and self.marked[w]: # 如果边的两个顶点都已经在树里就跳过这个边 continue self.mst.append(e) # 将边加入最小生成树 if not self.marked[v]: self.visit(G, v) if not self.marked[w]: self.visit(G, w) def visit(self, G, v): """ 将顶点加入最小生成树 """ self.marked[v] = True for e in G.adj(v): # 将另一个顶点不在最小生成树中的邻接边加入横切边中 if not self.marked[e.other(v)]: self.pq.insert(e) def edges(self): return self.mst def weight(self): weights = 0 for e in self.mst: weights += e.weight() return weights