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

     

     

    所谓生成树,就是n个点之间连成n-1条边的图形。而最小生成树,就是权值(两点间直线的值)之和的最小值。首先,要用二维数组记录点和权值。如上图所示无向图:

    int map[7][7];
           map[1][2]=map[2][1]=4;
           map[1][3]=map[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;

     

        3.如此类推...

     
     
         当所有点都连同后,结果最生成树如上图所示。
        所有权值相加就是最小生成树,其值为2+1+2+4+3=12。
        至于具体代码如何实现,现在结合hdu1233例题解释。代码如下:
     
     
    #include<stdio.h>
    #include<string.h>
    #define MAX 0x3f3f3f3f
    //创建map二维数组储存图表,low数组记录每2个点间最小权值,visit数组标记某点是否已访问
    int map[1000][1000],low[1100],visit[1100],n;
    int prim()
    {
     int i,pos,min,sum=0,j;
     memset(visit,0,sizeof(visit));
    //从某点开始,分别标记和记录该点
     visit[1]=1;
     pos=1;
    //第一次给low数组赋值
     for(i=1;i<=n;i++)
      if(i!=pos)
      low[i]=map[pos][i];
    //再运行n-1次 
     for(i=1;i<n;i++)
     {
    //找出最小权值并记录位置
      min=MAX;
      for(j=1;j<=n;j++)
      {
       if(visit[j]==0&&min>low[j])
       {
        min=low[j];
        pos=j;
       }
      }
    //最小权值累加
           sum+=min;
    //标记该点
        visit[pos]=1;
    //更新权值
        for(j=1;j<=n;j++)
        {
         if(visit[j]==0&&low[j]>map[pos][j])
          low[j]=map[pos][j];
        }
     }
     return sum; 
    }
    int main()
    {
       int m,j,i,a,b,c;
       while(~scanf("%d",&n)&&n)
       {
        m=n*(n-1)/2;
    //所有权值初始化为最大
        memset(map,MAX,sizeof(map));
        for(i=1;i<=m;i++)
        {
         scanf("%d%d%d",&a,&b,&c);
         map[a][b]=map[b][a]=c;
        }
        printf("%d ",prim());
       }
    }
  • 相关阅读:
    第123天:移动web开发中的常见问题
    第122天:移动端开发常见事件和流式布局
    第121天:移动端开发基本知识
    第120天:移动端-Bootstrap基本使用方法
    第119天:移动端:CSS像素、屏幕像素和视口的关系
    加入收藏 设为首页代码收藏本页的代码和收藏本站的代码设为首页代码
    JQuery和UpdatePannel的问题
    JS中apply与call的用法
    Sumlime text3 安装包、汉化包、注册码
    使用WITH AS提高性能简化嵌套SQL
  • 原文地址:https://www.cnblogs.com/lxm940130740/p/3276903.html
Copyright © 2011-2022 走看看