基于邻接矩阵存储的图的最小生成树的Prime算法

来源:互联网 发布:moment软件使用方法 编辑:程序博客网 时间:2024/06/05 18:17
#include <iostream>

using namespace std;
#define MAXNODE 500//最大顶点个数
#define Inf 65535//无穷大
typedef char vertype;
struct VerNode
{
    vertype vertex;//// 顶点信息,可以是字母表示,也可以是数字表示
    //.....;//// 和顶点相关的其它信息,如顶点的度
};
struct Arc
{
    int adj;// 两顶点之间是否存在关系,用1或0表示相邻否;如果是带权图,则为权值类型
    //....;// 和弧(或边)相关的信息,如弧头、弧尾
};
struct MGraph//图的邻接矩阵表示类型
{
    VerNode vex[MAXNODE];//顶点向量
    Arc arcs[MAXNODE][MAXNODE];//邻接矩阵
    int vexnum,arcnum;//图的当前顶点数和弧数
};
int sum=0;//保存所走路径的花费
MGraph CreatMGraph(MGraph g)//创建邻接矩阵
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>g.vex[i].vertex;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            g.arcs[i][j].adj=Inf;//初始化邻接矩阵,各顶点间无路
        }
    }
    int i,j,quan,e=0;
    cin>>i>>j;//输入一条边依附顶点的序号
    cin>>quan;
    while(i&&j)//两顶点之一为0表示结束
    {
        e++;
        g.arcs[i][j].adj=quan;g.arcs[j][i].adj=quan;
        cin>>i>>j;cin>>quan;
    }
    g.vexnum=n;
    g.arcnum=e;
    return g;
}
int GraphLocateVertex(MGraph g,vertype v)//返回顶点v在图中的位置
{
    for(int i=1;i<=g.vexnum;i++)
    {
       if(g.vex[i].vertex==v)
            return i;
    }
    return -1;
}
void MiniSpanTreer_Prime(MGraph g,vertype v)
{//用Prime算法从第u个顶点出发构造以邻接矩阵存储的网G的最
//小生成树T,并且输出T的各条边
struct Closedge
{
    vertype adjvex;//最小代价边依附的始顶点
    int lowcost;// 最小代价
}closedge[MAXNODE];
int k=GraphLocateVertex(g,v);//任意选取一个顶点u出发,返回顶点v在图中的位置
int minimum;//保存生成树的下一个结点
int min=10000000;
for(int i=1;i<=g.vexnum;i++)
{
    if(i!=k)
    {
        closedge[i].adjvex=v;
        closedge[i].lowcost=g.arcs[k][i].adj;
        if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)
        {
            min=closedge[i].lowcost;
            minimum=i;
        }
    }
}
closedge[k].lowcost=-1;
cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
for(int i=2;i<=g.vexnum;i++)
{
    k=minimum;//此时closedge[k].lowcost=MIN{closedge[vi].lowcost |closedge [vi].lowcost >0, vi属于V-U}
    sum+=closedge[k].lowcost;
    cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
    closedge[k].lowcost=-1;//第k结点并入U集并置权值为-1,表示该顶点已经遍历过
    min=10000000;
    for(int i=1;i<=g.vexnum;i++)
    {
        if(g.arcs[k][i].adj<closedge[i].lowcost)//新顶点并入U后
        {
            closedge[i].adjvex=g.vex[k].vertex;
            closedge[i].lowcost=g.arcs[k][i].adj;
        }
        if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)//重新选择最小边
        {
            min=closedge[i].lowcost;
            minimum=i;
        }
    }
//    for(int i=1;i<=g.vexnum;i++)
//    {
//        cout<<closedge[i].adjvex;
//        cout<<" "<<closedge[i].lowcost<<" ";
//    }
//    cout<<endl;
}
}
int main()
{
    MGraph g= CreatMGraph(g);
    vertype v;
    cin>>v;
    //cout<<g.vexnum<<"  "<<g.arcnum<<endl;
    MiniSpanTreer_Prime(g,v);
    cout<<"所需花费为:"<<sum<<endl;
    return 0;
}

原创粉丝点击