克鲁斯卡尔算法
把所有的边按照权值的大小进行排序,然后从小到大依次遍历
如果该边的 两个端点在同一个集合之中(刚开始所有的顶点都是一个单独的集合) 就直接跳过,如果不在一个集合之中,就利用并查集combine函数把这两个点放在一个集合里,然后将该边加入最小生成树。
迪杰斯特拉算法
基于优先队列的使用
创建一个优先队列
设置 dis[i]为 起点到顶点i的最小距离!
起初所有dis值都设置成最大值INF
设置顶点1为起点
dis[1]=0
所以起初,将距离{0,1}(距离,顶点编号)放入优先队列
然后每次拿出优先队列中的第一个元素
然后将该顶点利用vis数组进行标记
遍历与该顶点相邻的所有顶点 i(并且是未被vis数组标记过的)
判断 dis[i] 和 dis[1]+两顶点间距离 的大小,如果后者更小,那么就对
dis[i]进行更新替换,然后将新的信息{dis[i],i}放入队列之中,如此反复直到队列为空,算法完成!
普利姆算法
我们设置编号为1的顶点为起点,此时我们设置两个集合,一个集合是:已经加入最小生成树的顶点集合S,另一个是暂时未加入最小生成树的顶点集合U。
设置 一个数组 dis,表示将该点加入最小生成树的最小代价。起初 只有dis[1]=0(起点),然后其他值都设置成最大值INF
设置一个数组 vis。表示该点已加入最小生成树!
每次找出那些没被vis标记过,且dis数值最小的一个顶点 i
将dis[i]累加到答案中,然后将点用vis标记, 表示将该点加入最小生成树。
然后也是最重要的,对所有点(没被vis标记过)的dis值进行更新
判断 原本dis值 和 从顶点 i 出发到该点距离的大小(如果这两个点不相邻,那么两点距离为最大值INF)。取最小值对dis数组进行更新!
上述操作可使一个节点加入最小生成树,重复上述操作n次,即可得到答案,时间复杂度为 O(n^2)