项湫

导航

Prim算法生成最小生成树


 

1. 问题

最小生成树:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边

2. 解析

 

在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T G 的最小生成树。

 

Prim算法: Prim算法构建最小生成树的过程是:先构建一棵只包含根结点V1的树A,然后每次在连接树A结点和图G中树A以外的结点的所有边中,选取一条权重最小的边加入树A,直至树A覆盖图G中的所有结点。

注意:

1)每次都选取权值最小的边,但不能构成回路,构成环路的边则舍弃。
2)遇到权值相等,又均不构成回路的边,随意选择哪一条,均不影响生成树结果。
3)选取n-1条恰当的边以连通n个顶点。

3. 设计

[核心伪代码]

4. 分析

算法步骤执行O(n)次 时间复杂度T(n)=O(n)

5. 源码

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<math.h>

#define MAX 100000

#define VNUM 10+1 /*?啥意思*/

 

int edge[VNUM][VNUM] = {/*输入邻阶矩阵*/ };

int lowcost[VNUM] = { 0 };

int addvnew[VNUM];

int adjecent[VNUM] = { 0 };

 

void prim(int start) {

int sumweigth = 0;

int i, j, k = 0;

 

for (i = 1; i < VNUM; ++i) {//从顶点1开始

lowcost[i] = edge[start][i];

addvnew[i] = 1;

}

addvnew[start] = 0;//将起始点start加入VNUM

adjecent[start] = start;

for (i = 1; i < VNUM - 1; ++i) {

int min = MAX;

int v = -1;

for (j = 1; j < VNUM; ++j) {

if (addvnew[j] != -1 && lowcost[j] < min) {

min = lowcost[j];

v = j;

}

}

if (v != -1) {

printf("%d %d %d\n", adjecent[v], v, lowcost[v]);

addvnew[v] = 0;

sumweigth += lowcost[v];//计算路径长度的和

for (j = 1; j < VNUM; ++j) {

if (addvnew[j] == -1 && edge[v][j] < lowcost[j]) {

lowcost[j] = edge[v][j];

adjecent[j] = v;

}

}

}

}

printf("最小的权值为 %d",sumweigth);

}                                    

posted on 2021-03-08 23:02  项湫  阅读(436)  评论(0编辑  收藏  举报