zoukankan      html  css  js  c++  java
  • 生成最小树prim算法

    最小生成树prim算法实现

     

    ‘      ’最小生成树,就是权值(两点间直线的值)之和的最小值。

      

             首先,要用二维数组记录点和权值。如上图所示无向图:

    int G[6][6];
           G[1][2]= G[2][1]=4;
           G[1][3]= G[3][1]=2;
           ......

          然后再求最小生成树。具体方法是:

    1.先选取一个点作起始点,然后选择它邻近的权值最小的点(如果有多个与其相连的相同最小权值的点,随便选取一个)。如1作为起点。

    使用全局变量来用做标记      visited[1]=1;

    pos=1;

    //用low[]数组不断刷新最小权值,low[i](0<i<=点数)的值为:i点到邻近点(未被标记)的最小距离。

    low[1]=0;  //起始点i到邻近点的最小距离为0

    low[2]=map[pos][2]=4;

    low[3]=map[pos][3]=2;

    low[4]==map[pos][4]=3;

    low[5]=map[pos][5]=MaxInt;  //无法直达

    low[6]=map[pos][6]=MaxInt;

      2.再在伸延的点找与它邻近的两者权值最小的点。

    //low[]以3作当前位置进行更新

    visited[3]=1;

    pos=3;

    low[1]=0;                                                //已标记,不更新

    low[2]=map[1][2]=4;                               //比5小,不更新

    low[3]=2;                                                //已标记,不更新

    low[4]=map[1][4]=3;                             //比1大,更新后为:low[4]=map[3][4]=1;

    low[5]=map[1][5]=MaxInt;                       //无法直达,不更新

    low[6]=map[1][6]=MaxInt;                     //比2大,更新后为:low[6]=map[3][6]=2;

     -----------------------------------------------------------------------------------------------------------------------------------------------

    是最小值而又没有被标记的为low[4]

    visited[4]=1;

    pos=4;

    low[1]=0;                                       //已标记不更新

    low[2]=map[1][2]=4;                      //map[4][2] == 4 一样大不更新

    low[3]=2;                                     //已标记不更新

    low[4]=map[1][4]=1;                     //已标记不更新

    low[5]=map[4][5]=6;                     //比max小更新

    low[6]=map[4][6]=2;                      //和map[3][6]一样大不更新

    -------------------------------------------------------------------------------------------------------------------------------------------------

    是最小值而又没有被标记的为low[6]

    visited[2]=1;

    pos=4;

    low[1]=0;                                       //已标记不更新

    low[2]=map[1][2]=4;                      //已标记不更新

    low[3]=2;                                     //已标记不更新

    low[4]=map[1][4]=1;                     //已标记不更新

    low[5]=map[6][5]=4;                     //比map[4][5]小更新为3

    low[6]=map[4][6]=2;                      //已标记不更新

    --------------------------------------------------------------------------------------------------------------------------------------

    是最小值而又没有被标记的为low[2]

    visited[4]=1;

    pos=4;

    low[1]=0;                                       //已标记不更新

    low[2]=map[1][2]=4;                      //比它大不更新

    low[3]=2;                                     //已标记不更新

    low[4]=map[1][4]=1;                     //已标记不更新

    low[5]=map[2][5]=3;                     //比他小更新

    low[6]=map[4][6]=2;                      //已标记不更新

    ----------------------------------------------------------------------------------------------------------------------------------------------

    是最小值而又没有被标记的为low[5]

    visited[4]=1;

    pos=4;

    low[1]=0;                                       //已标记不更新

    low[2]=map[1][2]=4;                      //已标记不更新

    low[3]=2;                                     //已标记不更新

    low[4]=map[1][4]=1;                     //已标记不更新

    low[5]=map[6][5]=4;                     //已标记不更新

    low[6]=map[4][6]=2;                      //已标记不更新

    ------------------------------------------------------------------------------------------------------------------------------------------------

        3.如此类推...

     
     
         当所有点都连同后,结果最生成树如上图所示。

         所有权值相加就是最小生成树,其值为2+1+2+4+3=12。

    --------------------------------------------------------------------------------------------------------------------------------------------

    #include <cstdio>
    #include <cstdlib>
    //#define _OJ_
    #define max 999
    int visit[100];
    
    typedef struct Graph1
    {
        int nv;
        int ne;
        int G[100][100];
    } Graph1, *Graph;
    
    int
    prim_Graph(Graph g)
    {
        int i, j, i1, pos, result, min;
        int low[100];
        visit[1] = 1;  low[1] = 0; result = 0;       pos = 1;//从第一个开始
        for(i = 2;i <= g->nv; i++) {
        low[i] = g->G[pos][i];     printf("low%d == %d ", i, low[i]);}  printf("
    ");
    
        for(i = 1;i < g->nv; i++) {
          min = max;
             for(j = 1;j <= g->nv; j++) {
                if(visit[j] == 0 && min > low[j]) {
                    min = low[j];    pos = j;
               }
           }
    
        result += min;
        visit[pos] = 1;
        printf("pos == %d  ", pos);
        for(i1 = 1;i1 <= g->nv; i1++) {
          if(visit[i1] == 0 && low[i1] > g->G[pos][i1])
            low[i1] = g->G[pos][i1];                 //把没有访问过的与pos相邻的且权
                                                //重比原来小的就更改,否则保持原来最小的值
            printf("low%d == %d ", i1, low[i1]);
          }
          printf("
    ");
        }
         return result;
    }
    
    int main(int argc, char const *argv[]) {
    #ifndef _OJ_  //ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
    
        int i, j, v1, v2, weight, result;
        Graph g;
        g = (Graph) malloc (sizeof(Graph1));
        scanf("%d %d", &g->nv, &g->ne);
        for(i = 1;i <= g->nv; i++) {
           for(j = 1;j <= g->nv; j++) {
           g->G[i][j] = max;                //初始值赋最大
             }
         }
    
        for(i = 1;i <= g->ne; i++) {
        scanf("%d %d %d", &v1, &v2, &weight);
        g->G[v1][v2] = weight;         g->G[v2][v1] = weight;//建立无向图
         }
        for(i = 1;i <= g->nv; i++)
        visit[i] = 0;                                   //标记初始化为零
    
         result = prim_Graph(g);
         printf("%d
    ", result);
    
        return 0;
    }
    

      ------------------------------------------------------------------------------------------------------------------------------------------

    low2 == 4 low3 == 2 low4 == 3 low5 == 999 low6 == 999
    pos == 3 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 999 low6 == 2
    pos == 4 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 6 low6 == 2
    pos == 6 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 4 low6 == 2
    pos == 2 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 3 low6 == 2
    pos == 5 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 3 low6 == 2
    12

    -----------------------------------------------------------------------------------------------------------------------------------------------

    总而言之每一个low[]数组存入一个最小的权值,   如果遇到更小的便换为更小的;

    low[1]---v1

    low[2]----v2

    ------------------

    类似于在线处理,, 总保存最小的那一个;;;

  • 相关阅读:
    springboot集成Spring Security安全框架(一)入门程序
    Redis学习(三)Redis 配置
    javax.servlet.ServletException: Could not resolve view with name 'order/list' in servlet with name 'dispatcherServlet'
    com.mysql.cj.exceptions.DataReadException: Zero date value prohibited
    Redis学习(二)Redis的安装
    Redis学习(一)简介
    Registering current configuration as safe fallback point
    IntelliJ IDEA为类和方法自动添加注释
    github 创建新项目
    pypi 的使用
  • 原文地址:https://www.cnblogs.com/airfand/p/5022356.html
Copyright © 2011-2022 走看看