Prim法求最小生成树

Prim求最小生成树

参考资料

算法思想:

此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。

在图G(V,E)中,V是该图的所有顶点的集合,E是该图中所有边的集合

  1.图中所有顶点的集合为V,初始时令U={s},其中s是放入U的第一个顶点,随机选一个即可,T=V-U是未放入到集合的顶点的集合

  2.在两个集合U和T所组成的边中,选择代价最小的边,并入集合U中。

  3.重复上述步骤,直到U中有n个顶点为止,算法结束。

在这个算法中我们需要辅助数组来记录顶点U到T中的权最小的边

struct closedge
{
int adjvex;//最小边在U上的那个顶点
int lowcost;//记录最小边上的权值
};

实现算法:

Ps:  1.此算法输入的为完全图,也可以改成任意条边的图,只需改createGraphy()方法即可

       2.图的最大顶点数n<=100,顶点标号从0~n-1

       3.权值不能为负数

/**
*  prim方法生成最小生成树 2018-7-2-16:05
**/
#include <iostream>
#define inf 99999
using namespace std;
//生成邻接矩阵来存储U到V-U集合中的顶点的信息
struct closedg
{
    int adjvex;//最小边在u中的的顶点
    int lowcost;//最小边上的权值
};
int ch[100][100];
struct closedg  closedge[100];//邻接矩阵
int book[100]={0};//用来记录U中的顶点数

/**
*创建完全图
**/
void createGraphy(int n)
{    int m=n*(n-1)/2;
     int a,b,value;
     cout<<"输入边的顶点和权值:"<<endl;
    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>value;
        ch[a][b]=value;
        ch[b][a]=value;
    }
    for(int i=0;i<n;i++)
    ch[i][i]=inf;

}
/**
*返回最小的那个顶点
**/
int FindMinPoint(int n)
{  int index,min=inf;
    for(int i=0;i<n;i++)
    {
        if(book[i]==0&&closedge[i].lowcost<min)
        {
            index=i;
            min=closedge[i].lowcost;
        }
    }
    return index;
}
/**
*利用prim算法思想创建最小生成树,这里我们将编号为0的顶点最先放到
*U中
**/
void MinTree_Prim(int n)
{
    book[0]=1;
    //更新closeedge
    for(int i=0;i<n;i++)
    {
        closedge[i].adjvex=0;
        closedge[i].lowcost=ch[0][i];
    }
    //进行n-1次循环,因为V-U中有n-1个顶点
    for(int j=0;j<n-1;j++)
{
    int lowindex=FindMinPoint(n);
    book[lowindex]=1;
    //更新lowcost
    for(int i=0;i<n;i++)
    {
        if(book[i]==0&&closedge[i].lowcost>ch[lowindex][i])
        {
            closedge[i].adjvex=lowindex;
            closedge[i].lowcost=ch[lowindex][i];
        }
    }
}
}
void PrintMinTree(int n)
{  char c[]={'a','b','c','d','e','f'};
    for(int i=1;i<n;i++)
    cout<<c[i]<<"--"<<c[closedge[i].adjvex]<<endl;
}
int main()
{
int n;
cout<<"请输入顶点数:"<<endl;
cin>>n;
createGraphy(n);
for(int i=0;i<n;i++)
{
    for(int j=0;j<n;j++)
    cout<<ch[i][j]<<' ';
    cout<<endl;
}
MinTree_Prim(n);
PrintMinTree(n);
}

测试数据:

我从参考资料的那个博客中搜取的数据输出结果正确




posted @ 2018-07-02 17:31  sunchongwei  阅读(559)  评论(0编辑  收藏  举报