#include <bits/stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;

#define INFINITY 65535    //最大值∞
#define MAX_VERTEX_NUM 20 //最大顶点个数

typedef int Status;
typedef int VRType;
typedef char InfoType;
typedef int VertexType;
typedef enum
{
    DG,
    DN,
    UDG,
    UDN
} GraphKind; //{有向图,有向网,无向图,无向网}

typedef struct ArcCell
{
    VRType adj;     //VRType 是顶点关系类型。对无权图,用0或1表示相邻否;对带权图,则为权值类型
    InfoType *info; //该弧相关信息的指针
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs;                  //邻接矩阵
    int vexnum, arcnum;              //图的当前顶点数和弧数
    GraphKind kind;                  //图的种类标志
} MGraph;

typedef struct
{
    VertexType adjvex;
    VRType lowcost;
} CLOSEDGE;

/*******************************声明部分****************************************/
Status CreateUDN(MGraph *G);
//构造无向网
int LocateVex(MGraph G, VertexType v);
//确定v在G中的位置
int minimum(CLOSEDGE closedge[], int n);
//返回最小连接的顶点序号
void MiniSpanTree_PRIM(MGraph G, VertexType u);
//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边
//记录从顶点集U到V-U的代价最小的边的辅助数组定义
/*******************************函数部分****************************************/
Status CreateUDN(MGraph *G)
{
    printf("\n构造无向网\n");
    int i, j, k;       //i,j,k用于计数
    int w;             //权重
    VertexType v1, v2; //弧头,弧尾

    printf("请输入顶点个数:");
    scanf("%d", &(*G).vexnum);
    printf("请输入弧个数:");
    scanf("%d", &(*G).arcnum);
    //假定该图不含其他信息
    int IncInfo = 0;

    for (i = 0; i < (*G).vexnum; i++)
    { //构造顶点向量
        printf("请输入G.vexs[%d] = ", i);
        scanf("%d", &(*G).vexs[i]);
    } //for

    for (i = 0; i < (*G).vexnum; i++) //初始化邻接矩阵
        for (j = 0; j < (*G).vexnum; j++)
        {
            (*G).arcs[i][j].adj = INFINITY; //无向网
            (*G).arcs[i][j].info = NULL;
        }

    for (k = 0; k < (*G).arcnum; k++)
    {                                   //构造邻接矩阵
        printf("请输入弧头(初始点):"); //输入一条弧的始点和终点
        scanf("%d", &v1);
        printf("请输入弧尾(终端点):");
        scanf("%d", &v2);
        printf("请输入权重:");
        scanf("%d", &w);

        i = LocateVex(*G, v1);
        j = LocateVex(*G, v2);

        if (i >= 0 && j >= 0)
            (*G).arcs[i][j].adj = (*G).arcs[j][i].adj = w; //置<v1,v2>的对称弧<v2,v1>

        //不再输入该弧含有的相关信息
    }
    (*G).kind = UDN;
    return OK;
}

int LocateVex(MGraph G, VertexType v)
{
    int ct;
    for (ct = 0; ct < G.vexnum; ct++)
        if (G.vexs[ct] == v)
            return ct;
    return -1;
}

int minimum(CLOSEDGE closedge[], int n)
{
    int i = 0, j, min, k;
    while (!closedge[i].lowcost)
        i++;
    min = closedge[i].lowcost;
    k = i;
    for (j = 1; j < n; j++)
        if (closedge[j].lowcost)
            if (min > closedge[j].lowcost)
            {
                min = closedge[j].lowcost;
                k = j;
            } //if
    return k;
}

void MiniSpanTree_PRIM(MGraph G, VertexType u)
{
    CLOSEDGE closedge[G.vexnum + 1];
    int k, j, i;

    k = LocateVex(G, u);
    for (j = 0; j < G.vexnum; ++j)
        if (j != k)
        { //辅助数组初始化
            closedge[j].adjvex = u;
            closedge[j].lowcost = G.arcs[k][j].adj;
        } //if

    closedge[k].lowcost = 0; //初始,U = {u}
    for (i = 1; i < G.vexnum; ++i)
    { //选择其余G.vexnum-1个顶点

        k = minimum(closedge, G.vexnum);                    //求出T的下一个结点:第k个顶点
        printf("(%d,%d)\n", closedge[k].adjvex, G.vexs[k]); //输出生成树的边

        closedge[k].lowcost = 0; //第k顶点并入U集

        for (j = 0; j < G.vexnum; ++j)
        {
            if (G.arcs[k][j].adj < closedge[j].lowcost)
            { //新顶点并入U集后重新选择最小边
                closedge[j].adjvex = G.vexs[k];
                closedge[j].lowcost = G.arcs[k][j].adj;
            } //if
        }     //for
    }         //for
}

/*******************************主函数部分**************************************/

int main()
{
    MGraph G;
    printf("P174 图7.16(a)\n");
    CreateUDN(&G);
    printf("\n输出生成树上的5条边为:\n");
    MiniSpanTree_PRIM(G, 1);
    return 0;
}

原文地址:http://www.cnblogs.com/south-wood/p/16907646.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性