CS61B - Lec 31 - Minimum Spanning Trees

一个Warm-up question: 给定一个graph,判断里面有没有cycle。
方案1:直接遍历,如果遍历到了marked的点,就说明有cycle。需要O(V+E)的复杂度。
CS61B - Lec 31 - Minimum Spanning Trees
方案2:利用并查集。从根节点开始遍历,union其它节点。如果发现跟当前节点connected的节点,那证明有cycle。
CS61B - Lec 31 - Minimum Spanning Trees
这一章讲的是最小生成树,越来越抽象了。以上问题的算法最后会用到。

MST, Cut Property, Generic MST Algorithm

上MST的定义。

  • spanning tree:对于一个无方向graph,spanning tree是它的一个子graph。首先它包含树的性质,没有cycle,所有节点全部相连。并且有spanning的性质,包含该graph的所有节点。
  • minimum spanning tree: 拥有最小weight的spanning tree。

CS61B - Lec 31 - Minimum Spanning Trees
MST和SPT(shortest path tree)是完全不同的两个概念。SPT是source到其他节点的距离,而MST是graph的一个属性,跟source无关。下图例子显示了,有的时候对所有节点应用SPT算法,也不能正确得出MST。
CS61B - Lec 31 - Minimum Spanning Trees
下面提出cut, crossing edge, cut property的概念,准备提出新的最小生成树算法。

  • cut: 把graph的节点分成两部分
  • crossing edge: 在cut之后,连接graph两个部分的一条边
  • cut property: 一条定理。对于任何cut,最小的crossing edge一定在MST上

CS61B - Lec 31 - Minimum Spanning Trees
可以用反证法证明该定理:假设minimum crossing edge不在MST上。对于这条边连接的graph的两部分,肯定也有一条crossing edge在MST上,因为MST需要连接所有的顶点。那么将这条边换成minimum crossing edge,MST的weight会更小,所以此时的MST不是真正的MST,矛盾。

到这里可以得出MST的算法:

  • 先cut graph,不过得保证crossing edges都不在MST上
  • 然后向MST中加入minimum crossing edge
  • 重复

CS61B - Lec 31 - Minimum Spanning Trees
最大的问题是第一步,如何找到所有crossing edges都不在MST中的cut呢?

Prim’s Algorithm

Prim算法是这样的:从某个节点开始,加入和已经形成的tree距离最小的节点。
CS61B - Lec 31 - Minimum Spanning Trees
想想看,如果逐个添加节点,cut的两部分就是已经形成的tree和剩下的节点,这肯定保证了两部分之间的连线不包含在tree中。

Prim算法的实现非常像Dijkstra算法。只不过将到根节点的距离换成到tree的距离。按照到tree的距离的一个BFT算法。不多说了。

CS61B - Lec 31 - Minimum Spanning Trees
CS61B - Lec 31 - Minimum Spanning Trees
分析runtime。insert和delete都是V次,每次O(log V)。每次decrease priority会花费O(log V),共有E次。这里E次还是不太懂
CS61B - Lec 31 - Minimum Spanning Trees

Kruskal’s Algorithm

Kruskal算法实现起来更加简单。首先把所有的边按照weight排序,然后逐个添加edge到MST中,除非加入后会产生cycle。

假设要向MST中加入顶点v和w组成的edge。可以想象,这条edge是连接两个side的(两个顶点各自的集合)。加入后不产生cycle,保证了目前两个side间没有任何crossing edge在MST中;按照weight从小到大添加,保证了此时没有任何crossing edge比这条edge大,由之前的property,可以证明这条edge一定在MST上。
CS61B - Lec 31 - Minimum Spanning Trees
实现。这会就用到了开头说的如何判断cycle的方法。
CS61B - Lec 31 - Minimum Spanning Trees
分析runtime。共有按照顺序insert到PQ,delete最小PQ,以及并查集的union和isConnected。
CS61B - Lec 31 - Minimum Spanning Trees
CS61B - Lec 31 - Minimum Spanning Trees