最小生成树
最小生成树仅仅针对无向图
是否成环
参考链接
这里直接用carl给的模板
1 | int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好 |
通过模板,我们可以知道,并查集主要有三个功能。
- 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
- 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
- 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点
一个误区
1 | // 判断 u 和 v是否找到同一个根 |
这里不能直接将isSame抽象出来,在join里面调用,必须寻根以后再father[v] = u;
寻根以后的u v 和 join传入的参数u v 是不一样的!!!
并查集只能判断无向图是否成环
1 | public class test4 { |
通过这个例子可以看到,t.join(1, 3);还是t.join(3, 1); 最后判断t.isSame(1, 3)都会是true
Kruskal
Kruskal.java
1 | import java.util.*; |
结果
Prim
普通写法
Prim.java
1 | public class Prim { |
最小生成树的结果不唯一
上述代码的运行结果为
另外一种树为,权值和均为37
优先级队列的写法
Prim2.java
1 | import java.util.PriorityQueue; |
优先级队列的思想还是比较容易理解的,刚好其输出是另外一颗最小树,也刚好验证了上面的说法