您的位置:首页 > 其它

kruscal算法求最小生成树总结

2016-01-10 22:29 295 查看
生成树指无向图中包含图的所有节点,边集为原图子集的图;

最小生成树指权值最小的生成树,对于包含n个节点的无向图来说,它的最小生成树包含n-1条边。

kruskal算法求解最小生成树的基本步骤如下:

1.数据结构表达:

u[maxn],v[maxn],w[maxn] 用来表示边的信息,在kruskal算法中,虽然最小生成树是是无向图,但是也只需要存储一条边的信息即可,例如若已存储(1,2,3),则边(2,1,3)便没有必要存储!

p[maxn] 存储节点所在连通分量的父亲下标

r[maxn] 存储边排序后的下标,间接排序法!

kruskal算法自然语言描述

1,对所有边排序

2, 从最小的边到最大的边

{

如果这条边的首节点和尾节点不在一个连通分量,把他们合并。

}

3,代码描述

for(int i=1;i<=m;i++)//初始化每个节点的父亲为自己

p[i]=i;

for(int i=1;i<=m;i++)

r[i]=i;

sort(r+1,r+m+1,cmp);//间接排序

for(int i=1;i<=m;i++) //遍历m条边

{

int e=r[i];

int x=Find(u[e]);

int y=Find(v[e]);

if(x!=y) //如果这条边的始点和终点不在一个连通分量

{

ans+=w[e];

p[x]=y;

}

}

以下是杭电1102题目代码(AC)

#include <iostream>

#include <algorithm>

#include <cstdio>

using namespace std;

const int MaxN=105;

const int MaxM=MaxN*(MaxN+1);

int weight[MaxN][MaxN];

int u[MaxM],v[MaxM],w[MaxM];

int p[MaxM];

int r[MaxM];

int cmp(const int i,const int j)

{

return w[i]<w[j];

}

int Find(int x)

{

return p[x]==x?x:p[x]=Find(p[x]);

}

int main()

{

int n;

while(scanf("%d",&n)!=EOF)

{

for(int i=1;i<=n;i++)

{

for(int j=1;j<=n;j++)

{

scanf("%d",&weight[i][j]);

}

}

int q;

scanf("%d",&q);

for(int i=1;i<=q;i++)

{

int first,last;

scanf("%d%d",&first,&last);

weight[first][last]=weight[last][first]=0;

}

int num=1;

for(int i=1;i<=n;i++)

{

for(int j=1;j<=n;j++)

{

if(i!=j)

{u[num]=i; v[num]=j; w[num]=weight[i][j]; num++; }

}

}

int ans=0;

int m=num-1;

for(int i=1;i<=m;i++)

p[i]=i;

for(int i=1;i<=m;i++)

r[i]=i;

sort(r+1,r+m+1,cmp);

for(int i=1;i<=m;i++)

{

int e=r[i];

int x=Find(u[e]);

int y=Find(v[e]);

if(x!=y)

{

ans+=w[e];

p[x]=y;

}

}

printf("%d\n",ans);

}

return 0;

}

/*

4

0 300 500 200

300 0 400 100

500 400 0 600

200 100 600 0

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: