kruscal算法求最小生成树总结

来源:互联网 发布:战地4m98b数据 编辑:程序博客网 时间:2024/05/16 14:37

生成树指无向图中包含图的所有节点,边集为原图子集的图;

最小生成树指权值最小的生成树,对于包含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
*/





0 0
原创粉丝点击