最小生成树定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。
1.Prim算法:刷新每条边联通生成树的最小权值最后完成最小生成树
变量:
n:结点个数
i(i=1,i≤n,++i):循环n次,每次与生成树联通一个结点
j(j=1,j≤n,++j):枚举结点
k:当前循环被染色的点
book[]:记录染色(0,1)
minn[]:记录每个点与生成树相连所需最小权值
edge[][]:记录权值
如图,一个有4(n)个结点的连通图,求其最小生成树权值之和
首先将k(k=1)作为根节点,并存入生成树内,将其染色(book[j]=1)
枚举j结点到节点k的权值(book[j]=0),更新j与生成树联通的最小权值(minn[j]=min(minn[j],edge[k][j])),minn[]={0,1,3,2},进入下一轮循环(++i)。
贪心,枚举minn数组中的最小值(book[j]=0),记录下标(k=j),并将k(k=2)存入生成树(book[k]=1)
注:每次minn数组的权值最小值一定不会再更新,故可以直接存入生成树,可参考Dijkstra
以此类推,更新minn[]的值,直到将所有节点存入生成树为止
最终minn[]={0,1,2,1}即edge[1][2],edge[2][3],edge[3][4],权值和为4
2.Kruskal:相对比Prim来说,Kruskal更好理解,其实无异于并查集
如图,一个有4个结点的连通图,求其最小生成树权值之和
现将其边的权值进行排序{1,1,2,2,2,3},并将四个节点分为四个集合{{1},{2},{3},{4}}
枚举其权值,首先是最小的edge[1][2],1和2不在同一个集合中(在同一个集合直接跳过),使用并查集,将1和2合并到一个集合,三个集合{{1,2}{3}{4}},以此类推,下个循环是edge[3][4],不在同一集合,使用并查集,两个集合{{1,2}{3,4}},再下一个是edge[1][4],不在同一集合,使用并查集,一个集合{1,2,3,4},权值之和为4