A. 利用prim算法构造最小生成树
Prim算法是通过每次选择提条代价最小的边辑器相应 的顶点加入到最小生成树中,因此来构造最小生成树。
B. 利用PRIM算法生成最小生成树
普里姆算法. 普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类)。. 对于给定的连通网,起始状态全部顶点都归为 B 类。. 在找最小生成树时,选定任意一个顶点作为起始点,并将之从 B 类移至 A 类;然后找出 B 类中到 A 类中的顶点之间权值最小的顶点,将之从 B 类移至 A 类,如此重复,直到 B 类中没有顶点为止。. 所走过的顶点和边就是该连通图的最小生成树
C. 无权无向图,只给出节点个数,怎么用Prim算法求最小生成树
Prim算法的主要运行时间花在过程②的选边中。看起来复杂度是O(VE)=O(V^3)不是么,效率也太低了吧……
为了比较快速地选边,我们用两个数组lowcost、closest动态地维护每一个点到S的最短距离。在某一状态下,lowcost[i]表示所有与i相连且另一端点在S中的边中的权值最小值,closest[i]表示在S中且与i相连的点中与i之间距离最小的点。显然,lowcost[i]=w(i,closest[i])。需要注意的是两个数组记录的都是边而不是路径。若i没有边直接连向S,则lowcost[i]=∞。另外,若i已在S中,则lowcost[i]=0。
设出发点为x。初始时对于任意k∈V,closest[k]=x,lowcost[k]=w(k,x)【w(i,j)表示i、j间的距离。初始化时,若两点间没有边则w(i,j)赋为一个足够大的整数(如maxint),并且所有点到自身的距离赋为0,即w(i,i)=0】
每一次找出lowcost中不为0的最小值lowcost[i],然后把i加入S(即lowcost[i]:=0),然后对于图中所有点k,若w(k,i)<lowcost[k],则把lowcost[k]赋为w(k,i),把closest[k]赋为i。【由于S中所有点的lowcost都为0,所以只影响到S以外的点】
以上操作重复|V|-1次结束。由于每次加入S的点i都在当时取到了符合流程②的边min{lowcost},而lowcost[i]=w(i,closest[i]),所以此时的最小生成树的各边就是(i,closest[i]),i∈V且not (i=x)【需要注意的是出发点x的closest[x]还是x,所以应忽略,实际取到x-1条边】。把i从1取到|V|,便得到最小生成树T的每条边。
程序:
for(k= 1;k <= n; k++){ //x为S中的第一个点,x任选一个都可
lowcost[k] = w[x][k]; //lowcost表示k点到前集合的最小值,是k与前集合中的closet[k]间的距离
closest[k] = x;
} //初始化
for(i = 2; i <= n; i++){ //除去x,还要加入n – 1个点
temp = maxint;
for(j = 1; j <= n; j++)
if(lowcost[j] < temp && lowcost[j] != 0) {
temp = lowcost[j];
k = j;
} //找出S外距S最近的点k
lowcost[k] = 0; //将k加入生成树
for(j = 1; j <= n; j++)
if(w[k][j] < lowcost[j]){
lowcost[j] = w[k][j];
closest[j] = k;
} //由新加入S中的k点使某些点到S的距离缩短,所以更新各点的lowcost和closest,即再次初始化
}
for(i = 1; i <= n; i++)
if(i != closest[i]){
printf(“%d %d”, i, closest[i]);
} //输出最小生成树的各边
不难看出,以上算法包含一个二重循环,算法复杂度为O(V^2),与图的稠密度无关
D. prim算法构造出的最小生成树唯一吗prim算法和kruskal算法构造出的最小生成树一样吗
不唯一,两种算法构造出的最小生成不一定相同.
E. 已知图G如下所示,根据Prim算法,构造最小生成树。(要求给出生成过程)
①将带权连通图G=的各边按权从小到大依次排列,如e1,e2,…,em,其中e1的权最小,em的权最大,m为边数。 ②取权最小的两条边构成边集T0,即T0={e1,e2},从e3起,按次序逐个将各边加进集合T0中去,若出现回路则将这条边排除(不加进去),按此法一直进行到em,最后得到n-1条边的集合T0={e1,e2,…,en-1},则T0导出的子图就是图G的最小生成树。
F. 用prim算法求最小生成树:c语言
把main函数改成:
main(){
GraphMatrix graph = {
"abcd",
{{7,8,Max,15},{12,100,6,20},{Max,100,4,13},{Max,4,8,10}},
};
Edge mst[Max];
int i,j;
prim(graph,mst);
for(j=0;j<Max;j++)
{
printf("%c\t",mst[j].stop_vex);
printf("%c\t",mst[j].start_vex);
printf("%d\n",mst[j].weight);
}
}
还有GraphMatrix结构体里的vexs数组最好定义为vexs[VN+1]给字符串末尾的‘\0'留地方。