普利姆算法求最小生成树权值之和

允我心安 提交于 2019-12-15 11:47:00
#include<iostream>
#include<string.h>
using namespace std;
#define  Max 50

    typedef struct
        {
            char data; //顶点的数据
            int num;//顶点的数组下标
        }VertexType;

   typedef struct Gnode     //建立一个无向图
    {
        int Nv;//顶点数
        int Ne;//边数
        int G[Max][Max];   //最大max行  max列的矩阵
        VertexType vex[Max];

    }*Graph,graph;

    typedef struct ENode
        {
            int v1,v2; //有向边v1 v2
            int weight; //邻接矩阵里面的值都是两条边之间的权值
        }*Ptr,ptr;

 void init_Graph(Graph &L);
 void creat_graph(int vertexnum,Graph &L);  //所有顶点,一条边都没有
 void built_graph(Graph &L,int &e);
 void insert_Ne(Graph L,Ptr t);
 void built_graph(Graph &L);
 void printlist(Graph L); //打印邻接矩阵
 void prim(Graph &L,int v0,float &sum); //从V0开始求最小生成树

    int main()
        {
            int e; //返回边的数量
            Graph  L;
            init_Graph(L);
            built_graph(L,e);
            printlist(L);
            cout<<endl;
            int v1,v2,weight;
            Ptr s;
            for(int i=0;i<e;i++)
            {
                cout<<"请输入您顶点之间的边 和权值"<<endl;
                cin>>v1>>v2>>weight;
                s=new ptr;
                s->v1=v1;
                s->v2=v2;
                s->weight=weight;
                insert_Ne(L,s);
            }
           cout<<endl;
           printlist(L);
           float sum=0;
           prim(L,0,sum);
           cout<<"这个最小生成树权值之和为"<<sum<<endl;

        }

    void init_Graph(Graph &L)
        {
           L=NULL;
        }

    void creat_graph(int vertexnum,Graph &L)  //所有顶点,一条边都没有
        {
            if(L==NULL)
            {
                int v,m,i=0;
                L=new graph;
                L->Ne=0;
                L->Nv=vertexnum;// 定点数
                for(v=0;v<L->Nv;v++)
                {
                    for(m=0;m<L->Nv;m++)
                    {

                        L->G[v][m]=Max;
                    }
                    L->vex[v].data='A'+i;
                    L->vex[v].num=v;
                    i++;
                }
            }

            else
            {
                return ;
            }
        }

    void built_graph(Graph &L,int &e)
        {
            if(L!=NULL)
            {
                cout<<"已经有值了,不需要再建造了呦"<<endl;
            }

            else
            {
                int Vex;
                cout<<"您想创建几个顶点的图呢"<<endl;
                cin>>Vex;
                creat_graph(Vex,L);
                cout<<"你想创建条边呢"<<endl;
                cin>>L->Ne;
                e=L->Ne;
            }
        }

    void insert_Ne(Graph L,Ptr t)
        {
            L->G[t->v1][t->v2]=t->weight;
            L->G[t->v2][t->v1]=t->weight;
            L->Ne++;
        }


    void printlist(Graph L) //打印邻接矩阵
        {
            int i,j;
            for(i=0;i<L->Nv;i++)
            {
                cout<<i<<" ";
                cout<<L->vex[i].data<<" ";
                for(j=0;j<L->Nv;j++)
                {
                    cout<<L->G[i][j]<<" ";
                }
                cout<<endl;
            }

            cout<<endl;
        }


    void prim(Graph &L,int v0,float &sum) //从V0开始求最小生成树
        {
            int mins=Max;
            int LowCost[L->Nv];
            int Vset[L->Nv];
            memset(Vset,0,sizeof(Vset));
            int i,j,k;//i j为循环变量 k为要标记的下标
            for(i=0;i<L->Nv;i++)
            {
                LowCost[i]=L->G[v0][i];
            }
            Vset[v0]=1;

            for(i=0;i<L->Nv-1;i++)  //已经解决了一个节点,只需要再解决剩下的n-1个节点就 ok
            {
                mins=Max;
                for(j=0;j<L->Nv;j++)
                {
                    if(Vset[j]==0&&LowCost[j]<mins)
                    {
                        mins=LowCost[j];
                        k=j;
                    }
                }
                Vset[k]=1;
                sum+=mins;
                for(j=0;j<L->Nv;j++)
                {
                    if(Vset[j]==0&&LowCost[j]>L->G[k][j])
                    {
                        LowCost[j]=L->G[k][j];
                    }
                }

            }

        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!