zoukankan      html  css  js  c++  java
  • 最小生成树问题-prim算法求解

    MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从点 的方面考 虑构建一颗MST,大致思想是:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到 V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最 小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一 个点,就意味着找到一条MST的边。

    代码如下:

    #include "stdio.h"    
    #include "stdlib.h"   
    #include "io.h"  
    #include "math.h"  
    #include "time.h"
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    #define MAXEDGE 20
    #define MAXVEX 20
    #define INFINITY 65535
    
    typedef int Status;    /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    
    typedef struct
    {
        int arc[MAXVEX][MAXVEX];
        int numVertexes, numEdges;    //节点数量与边的数量
    }MGraph;
    
    void CreateMGraph(MGraph *G)/* 构建图 */
    {
        int i, j;
    
        /* printf("请输入边数和顶点数:"); */
        G->numEdges=15;
        G->numVertexes=9;
    
        for (i = 0; i < G->numVertexes; i++)/* 初始化图 */
        {
            for ( j = 0; j < G->numVertexes; j++)
            {
                if (i==j)
                    G->arc[i][j]=0;
                else
                    G->arc[i][j] = G->arc[j][i] = INFINITY;
            }
        }
    
        G->arc[0][1]=10;
        G->arc[0][5]=11; 
        G->arc[1][2]=18; 
        G->arc[1][8]=12; 
        G->arc[1][6]=16; 
        G->arc[2][8]=8; 
        G->arc[2][3]=22; 
        G->arc[3][8]=21; 
        G->arc[3][6]=24; 
        G->arc[3][7]=16;
        G->arc[3][4]=20;
        G->arc[4][7]=7; 
        G->arc[4][5]=26; 
        G->arc[5][6]=17; 
        G->arc[6][7]=19; 
    
        for(i = 0; i < G->numVertexes; i++)
        {
            for(j = i; j < G->numVertexes; j++)
            {
                G->arc[j][i] =G->arc[i][j];
            }
        }
    }
    
    /* Prim算法生成最小生成树 */
    void MiniSpanTree_Prim(MGraph G)
    {    
        int min, i, j, k;
        int adjvex[MAXVEX];        /* 保存相关顶点下标 */
        int lowcost[MAXVEX];    /* 保存相关顶点间边的权值 */
    
        //1.初始lowcost[]和adjvex[]数组
        lowcost[0] = 0;/* 初始化第一个权值为0,即v0加入生成树 */
                /* lowcost的值为0,在这里就是此下标的顶点已经加入生成树 */
        adjvex[0] = 0;            /* 初始化第一个顶点下标为0 */
        for(i = 1; i < G.numVertexes; i++)    /* 循环除下标为0外的全部顶点 */
        {
            lowcost[i] = G.arc[0][i];    /* 将v0顶点与之有边的权值存入数组 */
            adjvex[i] = 0;                    /* 初始化都为v0的下标 */
        }
    
        //2.从lowcost[]中找到最小权值
        for(i = 1; i < G.numVertexes; i++)
        {
            min = INFINITY;    /* 初始化最小权值为∞, */
                            /* 通常设置为不可能的大数字如32767、65535等 */
            j = 1;k = 0;
    
            //找出最小的权值及其所在的下标
            while(j < G.numVertexes)    /* 循环全部顶点 */
            {
                if(lowcost[j]!=0 && lowcost[j] < min)/* 如果权值不为0且权值小于min */
                {    
                    min = lowcost[j];    /* 则让当前权值成为最小值 */
                    k = j;            /* 将当前最小值的下标存入k */
                }
                j++;
            }
            //3.打印第一条权最小的边
            //adjvex[k]中存放较小权值所在的行,上面算得的k是较小权值所在的列
            printf("(%d, %d)
    ", adjvex[k], k);/* 打印当前顶点边中权值最小的边 */
            lowcost[k] = 0;
    
            //4.更新lowcost[],包含两个方面的更新
            /* 将当前顶点的权值设置为0,表示此顶点已经完成任务 */
            for(j = 1; j < G.numVertexes; j++)    /* 循环所有顶点 */
            {
                if(lowcost[j]!=0 && G.arc[k][j] < lowcost[j]) 
                {/* 如果下标为k顶点各边权值小于此前这些顶点未被加入生成树权值 */
                    lowcost[j] = G.arc[k][j];/* 将较小的权值存入lowcost相应位置 */
                    adjvex[j] = k;                /* 将下标为k的顶点存入adjvex */
                }
            }
        }
    }
    
    int main(void)
    {
        MGraph G;
        CreateMGraph(&G);
        MiniSpanTree_Prim(G);
      
        return 0;
     
    }


  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/Allen-win/p/7346417.html
Copyright © 2011-2022 走看看