• [讲解]prim算法<最小生成树>


    最小生成树的方法一般比较常用的就是kruskal和prim算法

    一个是按边从小到大加,一个是按点从小到大加,两个方法都是比较常用的,都不是很难。。。

    kruskal算法在本文里我就不讲了,本文的重点是讲讲prim算法,之前一直没学过,只是了解了思想,原本以为很难,结果很好理解

    prim 即可以用过邻接矩阵又可以用邻接链表,不过邻接链表的时间优化不了多少,但是还是可以优化很多空间的

     

    prim算法是先枚举第一个点,将选好的点加入点集V,没选的点在点集U,然后在U集中找距离V集最近一个点,然后将其加入U集

    我们还是用图来举例说明

    我们来模拟一遍这个过程。。。

    首先,lowcost表示从当前点到V集的最小距离,mst表示当前点到V集最小的那个V集的点

    我们先从1点开始。。。

    判断和1点相连的点,lowcost[2]=6,lowcost[3]=1,lowcost[4]=5,lowcost[5]=lowcost[6]=inf

               mst[2]=1,mst[3]=1,mst[4]=1;

    然后跑整个图的点,找到最小的lowcost并将这个点加入V集,从U集删除(删除操作即为把lowcost赋值为0)

    因为V集多了3,就更新整个图lowcost[2]=5,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4;

                 mst[2]=3,mst[4]=1,mst[5]=3,mst[6]=3;

    然后找整个U集发现lowcost最小是6点,V集加入6点,更新U集

    lowcost[2]=5,lowcost[4]=2,lowcost[5]=6

    mst[2]=3,mst[4]=6,mst[5]=3

    然后找lowcost最小的4点,加入V集,更新U集

    lowcost[2]=5,lowcost[5]=6

    mst[2]=3,mst[5]=3

    找lowcost最小的点2,加入V集,更新U集

    lowcost[5]=3,mst[5]=2

    加入V集,所有点都已经加入,完成操作,输出ans=15

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<queue>
     6 #include<algorithm>
     7 #include<cstdlib>
     8 #define maxn 1005
     9 using namespace std;
    10 
    11 int n,m,dis[maxn][maxn],ans;
    12 int lowcost[maxn],mst[maxn];
    13 
    14 int read(){
    15     int xx=0,ff=1;char ch=getchar();
    16     while(ch<'0'||ch>'9'){if(ch=='-')ff=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
    18     return xx*ff;
    19 }
    20 
    21 void prim(int u){
    22     for(int j=1;j<=n;j++){
    23         if(dis[u][j]>0){
    24             lowcost[j]=dis[u][j];mst[j]=u;
    25         }
    26     }
    27     mst[u]=0;lowcost[u]=0;
    28     int minid=0,minn=0x3f3f3f,tot=1;
    29     while(tot<n){
    30         minid=0,minn=0x3f3f3f;
    31         for(int i=1;i<=n;i++){
    32             if(lowcost[i]!=0&&lowcost[i]<minn){
    33                 minn=lowcost[i];
    34                 minid=i;
    35             }        
    36         }
    37         tot++;
    38         ans+=minn;
    39         mst[minid]=0;lowcost[minid]=0;
    40         for(int i=1;i<=n;i++){
    41             if(lowcost[i]!=0&&dis[minid][i]<lowcost[i]){
    42                 lowcost[i]=dis[minid][i];
    43                 mst[i]=minid;
    44             }
    45         }            
    46     }    
    47 }
    48 
    49 int main(){
    50     n=read();m=read();
    51     memset(dis,0x3f3f3f,sizeof(dis));
    52     for(int i=1;i<=m;i++){
    53         int x,y,v;
    54         x=read();y=read();v=read();
    55         dis[x][y]=dis[y][x]=v;
    56     }
    57     prim(1);
    58     printf("%d
    ",ans);
    59 }
    60 /*
    61 6 10
    62 1 3 1
    63 1 2 6
    64 1 4 5
    65 2 3 5
    66 3 4 5
    67 2 5 3
    68 3 5 6
    69 5 6 6
    70 3 6 4
    71 4 6 2
    72 */
    prim
  • 相关阅读:
    Java中替换字符串中特定字符,replaceAll,replace,replaceFirst的区别
    牛客剑指offer 67题(持续更新~)
    从尾到头打印链表
    字符串变形
    缩写
    删除公共字符
    替换空格
    二维数组的查找
    acm博弈论基础总结
    acm模板总结
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7747030.html
Copyright © 2020-2023  润新知