学习算法的最好方式,我认为是应从思考一些有趣的题目开始。学习一个算法之前要知道这个算法的价值是什么。
题目大意:询问你在各个村庄之间修公路,最少的花费是多少。
我们可以把“村庄"抽象成一个一个点,把”修公路的费用"抽象成连接两点的边值(权重)。
我们要求解决的是求出 把这些点(村庄)都连起来(修公路)时的所构成的树的权重总和最少(最少费用)是多少,即最小生成树的权重和。
如图:
注:生成树不含环路,且在有相同权重得情况下最小生成树可能不止一颗,但权重和一定相同。
则如何构建最小生成树成为重中之重!
下面介绍两种算法:Prim算法 和 Kruskal算法。
算法原理先介绍,证明会放在最后,因为这两种算法简单且看上去就像是那么回事~
Prim算法:
Prim算法的思想是:取图中任意一点作为起点放入树中,并向邻近树的点不断延伸,每次延伸的点要求满足到树的距离最短。
我们采用dis[]记录点离树的距离,并采用val[]标记在树中的点,两数组实时更新。
如图:
1:
2:
3:
4:
5: