生成树
生成树:指的是一个包含了G的所有顶点的树。生成树是G的一个极小连通的子图。从G的任意顶点出发,做一次深度/广度优先遍历,访问G中的n个顶点,并将顺次访问的两个顶点之间的路径记录,经历的n条边就构成了G的极小连通子图,也就是G的一棵生成树。
对于深度优先(DFS)和广度优先(BFS),只要在if语句中加入将(vi,vj)打印出来的语句,就构成生成树算法。
最小生成树
用一个连通网络来构造生成树时,可以得到一个带权的生成树,把生成树各边的权值总和作为生成树的权,具有最小权值的生成树构成了最小生成树。
构造最小生成树,就是在给定n个顶点对于的权矩阵条件下,给出代价最小的生成树。
构造最小生成树的算法MST性质
MST性质:假设G=(V,E)是一个连通网络,U是V中的一个子集,若存在顶点u属于U和v属于V-U的边(u,v)是一条具有最小权的边,则必存在G的一棵最小生成树包括这条边(u,v)。
非常拗口!多理解几遍。
看到教材上这张图,感觉会比较好理解。
根据MST性质,构造最小生成树有两种常用算法。
Prim算法(留坑)
算法梗概:
1、选一个任意顶点T,置初始候选边集
2、while{T中顶点数目小于n的时候:
3、从候选边集里找最短边(u,v)
4、将(u,v)放到T中,V-U中的点v加入到U中
5、调整候选边集}
图上真的好清楚啊!
//存储结构
typedef struct{
int fromvex,endvex; //边的起点和终点
float length; //边的权值
}edge;
float dist[n][n]; //n个顶点的带权邻接矩阵
edge T[n-1]; //生成树
//Prim算法
void Prim(int i){
//i是选取的第一个点下标。结果保存在T[n-1]中
int j,k,m,v,min,max=100000;
float d;
edge e;
v=i; //选定顶点放入中间变量v
for(j=0;j<=n-2;j++){
T[j