生成树和最小生成树
相关概念和算法思路详见这篇文章。
这里只对Prim算法和Kruskal算法的代码进行介绍。
Prim算法
U为当前的连通子图所包含的顶点集合,Prim算法的本质就是每次在V-U的顶点与U的顶点的连边中选出一条加入连通子图,U同时相应地改变,直到U使得图中的所有点连通。
//v为最小生成树的起始点,closest[i]为将编号为i的结点加入到集合U中,加入到连通子图的边的另一个端点
//lowcost[i]为当前U中的顶点能够与编号为i的结点相连的边的最小花费,如果无法加入或者已经加入花费为0
void Prim(MatGraph g,int v){
int lowcost[MAXV],closest[MAXV],k,min;
//将v加入到集合U中,修改与v相邻的顶点的lowcost和closest
for (int i=0;i<g.n;i++){
lowcost[i]=g.edges[v][i]; closest[i]=v;}
for (int i=1;i<g.n;i++){
min=INF;//将剩下的n-1个顶点加入到连通子图中
//寻找Y-U中能够加入到U的顶点的最小花费
for (int j=0;j<g.n;j++) if (lowcost[j]!=0&&lowcost[j]<min){
min=lowcost[j]; k=j;
}//打印加入的边的端点和权
printf(" 边(%d,%d)权为:%d\n",close