prim和kruscal算法得到的最小生成树是不是一样
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了prim和kruscal算法得到的最小生成树是不是一样相关的知识,希望对你有一定的参考价值。
prim 和 kruscal 的算法思想是什么了的。请再解释下。
应该不一样。可以用一个图根据两算法试一下,若一样,再修改图,之后应该就可以了。(百度或者查书本更加有效……)
构造G的最小生成树的Prim算法的基本思想是:首先置S=1,然后,只要S是V的真子集,就作如下的贪心选择:选取满足条件iS,jV-S,且c[i][j]最小的边,将顶点j添加到S中。
这个过程一直进行到S=V时为止。
Kruskal算法构造G的最小生成树:将所有的边按权从小到大排序。然后从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接2个不同的连通分支:当查看到第k条边(v, w)时,如果端点v和w分别是当前2个不同的连通分支T1和T2中的顶点时,就用边(v, w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k+1条边。这个过程一直进行到只剩下一个连通分支时为止 参考技术A 不唯一.如果最小生成树不唯一则用不同的算法就不唯一.关键路径是不会变的.非关键的可选路径是会变的.比如2.3和1.4.有可能1,4和2,3 .如果都是四个都2.任意选都是2.结果显然不一样.
当然.这个和初态有关 参考技术B 算法的思想应该是贪心,你要说是A*也可以
最小生成树算法之Prim算法
生成树
一个连通图的生成树是一个极小连通子图,它含有图中全部n个顶点和构成一棵树的(n-1)条边。
- 连通图由一次遍历就可以产生生成树
- 由深度优先遍历得到的生成树称为深度优先生成树。
- 由广度优先遍历得到的生成树称为广度优先生成树。
一个连通图的生成树不一定是唯一的!
最小生成树
对于带权连通图G (每条边上的权均为大于零的实数),可能有多棵不同生成树。
每棵生成树的所有边的权值之和可能不同。
其中权值之和最小的生成树称为图的最小生成树。
Prim算法
普里姆(Prim)算法是一种构造性算法,用于构造最小生成树。过程如下:
- 初始化U=v。v到其他顶点的所有边为候选边;
- 重复以下步骤n-1次,使得其他n-1个顶点被加入到U中:
- 从候选边中挑选权值最小的边输出,设该边在V-U中的顶点是k,将k加入U中;
- 考察当前V-U中的所有顶点j,修改候选边:若(j,k)的权值小于原来和顶点k关联的候选边,则用(k,j)取代后者作为候选边。
代码
Prim 算法构造生成树
//Prim 算法构造生成树
void Prim(MatGraph g, int v)
int lowcost[MAXV];//存储权值
int MIN;
int closest[MAXV], i, j, k;
//closet是用来存储与它相邻的节点的
for (i = 0; i < g.n; i++)
lowcost[i] = g.edges[v][i]; //初始化
closest[i] = v;
for (i = 1; i < g.n; i++)
MIN = INF;
for (j = 0; j < g.n; j++)
if (lowcost[j] != 0 && lowcost[j] < MIN)
MIN = lowcost[j];
k = j; //记录最近的节点的编号
printf("边(%d,%d)权为:%d\\n", closest[k], k, MIN);
lowcost[k] = 0;
for (j = 0; j < g.n; j++)
if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j]) //寻找有没有比较小的边
lowcost[j] = g.edges[k][j];
closest[j] = k;
测试代码
# include <stdio.h>
# include <stdlib.h>
#define ElemType int
#define maxsize 100
#define InfoType int
#define MAXV 100
#define MaxSize 100
#define INF 214748364
#define INFINITE INF
//邻接矩阵的数据类型
typedef struct s
int no; //顶点编号
InfoType info;//顶点的其他信息
VertexType; //顶点的类型
typedef struct SS
int edges[MAXV][MAXV]; //邻接矩阵的数组
int n, e; //图的顶点数和边数
VertexType vexs[MAXV]; //存放顶点信息
MatGraph;
///
//Prim 算法构造生成树
void Prim(MatGraph g, int v)
int lowcost[MAXV];
int MIN;
int closest[MAXV], i, j, k;
for (i = 0; i < g.n; i++)
lowcost[i] = g.edges[v][i]; //init
closest[i] = v;
for (i = 1; i < g.n; i++)
MIN = INF;
for (j = 0; j < g.n; j++)
if (lowcost[j] != 0 && lowcost[j] < MIN)
MIN = lowcost[j];
k = j; //记录最近的节点的编号
printf("边(%d,%d)权为:%d\\n", closest[k], k, MIN);
lowcost[k] = 0;
for (j = 0; j < g.n; j++)
if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j])
lowcost[j] = g.edges[k][j];
closest[j] = k;
//
void InitMatGraph(MatGraph & g, int a[][MAXV], int n, int e)
int i, j;
g.n = n;
g.e = e;
for(i = 0; i< n; i++)
for(j = 0; j < n; j++)
g.edges[i][j] = a[i][j];
int main ()
//注意无向带权图i=j是为0
int a[4][MAXV] = 0, 1, 3, 1,
1, 0, 2, 4,
3, 2, 0, INF,
1, 4, INF, 0;
MatGraph g;
InitMatGraph(g, a, 4, 5);
Prim(g, 0);
return 0;
测试结果
Enjoy
以上是关于prim和kruscal算法得到的最小生成树是不是一样的主要内容,如果未能解决你的问题,请参考以下文章
hdu1162(最小生成树 prim or kruscal)
hiho 1098 最小生成树二·Kruscal算法 (最小生成树)