1. 问题
给你一个N个节点M条边的无向图,每条边有一条权值。求改图的最小生成树的过程和权值。
2. 解析
求最小生成树有两种贪心算法prim和kruskal 。Prim算法是以点为核心记录起点到其他点的距离,每一步都是取图中还没有加入到最小生成树中距离最短的点加入到最小生成树种不断更新。
Kruskal算法则是以边为核心,先按照边升序,然后构造一个只有n个顶点,没有边的图。每次选最下边并且判断该边的两点是否属于两个联通分量,如果属于不同联通分量则加入到图中。
3. 设计
Prim(G, d[]){
d[初始化;
for (循环n次){
u = 使d[u]最小的还未访问的顶点的标号;
记u 已被访问;
for(从u出发到达的所有顶点v){
if (v未被访问&&以u为中介点使得v与集合S的最短距离d[v]更优){
将G[u][v]赋值给v与结合S的最短距离d[v];
}
}
}
}
Kruskal(){
Fa[]初始化;
For(i,1,m){
If(一条边的两个节点在不同的联通分量) {
加入边,并且将这两个节点的fa[a]=b;
}
}
}
4. 分析
Prim:时间复杂度O(N^2),它的执行时间与边数无关,只和点相关,要重复对n-1点进行遍历。
Kruskal:排序的复杂度 O(mlogm) ,并查集初始O(n) ,加边的复杂度O(m),总的复杂度就是O(mlogm).
5. 源码
https://github.com/xiaojunjun601/sfHomework1