zoukankan      html  css  js  c++  java
  • Minimum Spanning Trees

    Kruskal’s algorithm

    always union the lightest link if two sets haven't been linked

     1 typedef struct          
     2 {        
     3     char vertex[VertexNum];                                //顶点表         
     4     int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表         
     5     int n,e;                                               //图中当前的顶点数和边数         
     6 }MGraph; 
     7  
     8 typedef struct node  
     9 {  
    10     int u;                                                 //边的起始顶点   
    11     int v;                                                 //边的终止顶点   
    12     int w;                                                 //边的权值   
    13 }Edge; 
    14 
    15 void kruskal(MGraph G)  
    16 {  
    17     int i,j,u1,v1,sn1,sn2,k;  
    18     int vset[VertexNum];                                    //辅助数组,判定两个顶点是否连通   
    19     int E[EdgeNum];                                         //存放所有的边   
    20     k=0;                                                    //E数组的下标从0开始   
    21     for (i=0;i<G.n;i++)  
    22     {  
    23         for (j=0;j<G.n;j++)  
    24         {  
    25             if (G.edges[i][j]!=0 && G.edges[i][j]!=INF)  
    26             {  
    27                 E[k].u=i;  
    28                 E[k].v=j;  
    29                 E[k].w=G.edges[i][j];  
    30                 k++;  
    31             }  
    32         }  
    33     }     
    34     heapsort(E,k,sizeof(E[0]));                            //堆排序,按权值从小到大排列       
    35     for (i=0;i<G.n;i++)                                    //初始化辅助数组   
    36     {  
    37         vset[i]=i;  
    38     }  
    39     k=1;                                                   //生成的边数,最后要刚好为总边数   
    40     j=0;                                                   //E中的下标   
    41     while (k<G.n)  
    42     {   
    43         sn1=vset[E[j].u];  
    44         sn2=vset[E[j].v];                                  //得到两顶点属于的集合编号   
    45         if (sn1!=sn2)                                      //不在同一集合编号内的话,把边加入最小生成树   
    46         {
    47             printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w);       
    48             k++;  
    49             for (i=0;i<G.n;i++)  
    50             {  
    51                 if (vset[i]==sn2)  
    52                 {  
    53                     vset[i]=sn1;  
    54                 }  
    55             }             
    56         }  
    57         j++;  
    58     }  
    59 }

    Prim’s algorithm

    maintain a key of each vertex to represent the lightest  link which connected the vertex

    initial all the key as maximum, begin from a vertex and update the adjoin vertex key.

    #define MAX  100000
    #define VNUM  10+1                                             //这里没有ID为0的点,so id号范围1~10
    
    int edge[VNUM][VNUM]={/*输入的邻接矩阵*/};
    int lowcost[VNUM]={0};                                         //记录Vnew中每个点到V中邻接点的最短边
    int addvnew[VNUM];                                             //标记某点是否加入Vnew
    int adjecent[VNUM]={0};                                        //记录V中与Vnew最邻近的点
    
    
    void prim(int start)
    {
         int sumweight=0;
         int i,j,k=0;
    
         for(i=1;i<VNUM;i++)                                      //顶点是从1开始
         {
            lowcost[i]=edge[start][i];
            addvnew[i]=-1;                                         //将所有点至于Vnew之外,V之内,这里只要对应的为-1,就表示在Vnew之外
         }
    
         addvnew[start]=0;                                        //将起始点start加入Vnew
         adjecent[start]=start;
                                                     
         for(i=1;i<VNUM-1;i++)                                        
         {
            int min=MAX;
            int v=-1;
            for(j=1;j<VNUM;j++)                                      
            {
                if(addvnew[j]!=-1&&lowcost[j]<min)                 //在Vnew之外寻找最短路径
                {
                    min=lowcost[j];
                    v=j;
                }
            }
            if(v!=-1)
            {
                printf("%d %d %d
    ",adjecent[v],v,lowcost[v]);
                addvnew[v]=0;                                      //将v加Vnew中
    
                sumweight+=lowcost[v];                             //计算路径长度之和
                for(j=1;j<VNUM;j++)
                {
                    if(addvnew[j]==-1&&edge[v][j]<lowcost[j])      
                    {
                        lowcost[j]=edge[v][j];                     //此时v点加入Vnew 需要更新lowcost
                        adjecent[j]=v;                             
                    }
                }
            }
        }
        printf("the minmum weight is %d",sumweight);
    }
  • 相关阅读:
    Git Stash用法
    动态设置ImageView的宽高以及位置
    【算法笔记】B1047 编程团体赛
    【算法笔记】B1043 输出PATest
    【算法笔记】B1042 字符统计
    【算法笔记】B1039 到底买不买
    【算法笔记】B1038 统计同成绩学生
    【算法笔记】B1033 旧键盘打字
    【算法笔记】B1029 旧键盘
    【算法笔记】B1048 数字加密
  • 原文地址:https://www.cnblogs.com/wujunde/p/7161138.html
Copyright © 2011-2022 走看看