forked from hackfengJam/HelloAlgorithm
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPrimMST.java
79 lines (65 loc) · 1.72 KB
/
PrimMST.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package weight;
import java.util.ArrayList;
import java.util.List;
public class PrimMST {
/*
* 使用索引堆
* 优化后的 Prim 算法的实现
*
* */
private Graph G;
IndexMinHeap<Double> ipq;
List<Edge> edgeTo;
// 标记是否已经访问过
boolean[] marked;
// 最小生成树
List<Edge> mst;
// 最小生成树对应总权值
double mstWeight;
public PrimMST(Graph G) {
this.G = G;
this.ipq = new IndexMinHeap<>(this.G.V());
this.edgeTo = new ArrayList<>();
marked = new boolean[G.V()];
for (int i = 0; i < G.V(); i++) {
marked[i] = false;
edgeTo.add(null);
}
mst = new ArrayList<>();
// Lazy Prim
visit(0);
while (!ipq.isEmpty()) {
int v = ipq.delMinIndex();
assert (edgeTo.get(v) != null);
mst.add(edgeTo.get(v));
visit(v);
}
// 计算最小生成树总权值
for (Edge e : mst) {
mstWeight += e.wt();
}
}
private void visit(int v) {
assert (!marked[v]);
marked[v] = true;
Iterable<Edge> iterable = G.adj(v);
for (Edge e : iterable) {
int w = e.other(v);
if (!marked[w]) {
if (edgeTo.get(w) == null) {
ipq.insert(w, e.wt());
edgeTo.set(w, e);
} else if (e.wt() < edgeTo.get(w).wt()) {
edgeTo.set(w, e);
ipq.change(w, e.wt());
}
}
}
}
public List<Edge> mstEdges() {
return mst;
}
public double reuslt() {
return mstWeight;
}
}