这个比较简单,利用堆的思想,寻找该节点相邻节点最短的边,但是有个判断时一条边的两个点不能同时在一个阵营,即这条边就不是横切边了。
缺点: 有些边已经不是横切边却还在候选堆中,取出来还需要判断,这样效率不高。
核心代码:
private void visit(int v){
marked[v] = true;
// 将和节点v相连接的所有未访问的边放入最小堆中
for( Edge<Weight> e : G.adj(v) )
if( !marked[e.other(v)] )
pq.insert(e);
}
public LazyPrimMST(WeightedGraph<Weight> graph){
// 算法初始化
G = graph;
pq = new MinHeap<Edge<Weight>>(G.E());
marked = new boolean[G.V()];
mst = new ArrayList<Edge<Weight>>();
// Lazy Prim
visit(0);
while( !pq.isEmpty() ){
Edge<Weight> e = pq.extractMin();
if( marked[e.v()] == marked[e.w()] )
continue;
mst.add( e );
if( !marked[e.v()] )
visit( e.v() );
else
visit( e.w() );
}
// 计算权值
mstWeight = mst.get(0).wt();
for( int i = 1 ; i < mst.size() ; i ++ )
mstWeight = mstWeight.doubleValue() + mst.get(i).wt().doubleValue();
}