zoukankan      html  css  js  c++  java
  • MST_prim

        刚刚发了mst 的kruskal,现在再来一发,说一说prim咯。

        prim适用于稠密图。

        与kruskal不同,prim是从一个点开始,不断加入新的点直至连通所有点。

        讲讲prim的过程,我们假定有2个集合u和v,u存放所有已经加入的点,v存放还没有加入的点,先把点编号为0~n-1,从0点开始,把0加入u,我们扫描所有和0连接的点,不连接则为INF,把其中与0的边权值最小的点加入到u,再继续扫描连接u和v的所有边,把其中权值最小的边的点加入到u,再继续扫描所有连接u和v的边,把其中权值最小的边的点加入到u,嗯,就是这样一直扫描,直至所有点都在u。

    结合代码讲讲吧。

    下面这份代码也是来自fanal爷kuangbin,他的博客地址kuangbin.net,我不是抄袭,嗯,他说可以的。

    这里是使用邻接矩阵。

    标号从0开始,0~n-1

    代码手打,没有语法高亮。

    const int INF=0x3f3f3f;

    const int MAXN=110;//最大节点数

    bool vis[MAXN];//是否在集合u中,初始化为false

    int lowc[MAXN];//扫描时存储的边的信息,初始化为INF

    int cost[MAXN][MAXN];//初始化为INF

    int prim(int n)//传入n,返回最小权值 ,不连通,返回-1

    {

      int ans=0;//记得初始化

      memset(vis,false,sizeof(vis));

      vis[0]=true;//先拿一个点

      for(int i=1;i<n;i++)

       lowc[i]=cost[0][i];

      for(int i=1;i<n;i++)//从1开始,n-1次,拿n-1个点,若是节点编号为1~n,则从2开始,i<=n,也是拿n-1个点

      {

        int mic=INF;

        int p=-1;

        for(int j=0;j<n;j++)

        if(!vis[j]&&lowc[j]<minc)

        {

          minc=lowc[j];

          p=j;

        }

        if(minc==INF)

          return -1;

        ans+=minc;

        vis[p]=true;

        for(int j=0;j<n;j++)

        if(!vis[j]&&cost[p][j]<lowc[j])

          lowc[j]=cost[p][j];

      }

      return ans;

    }

  • 相关阅读:
    awk语法
    Linux 统计某个字符串出现的次数
    Linux 输出文件列数,拼接文件
    Linux之date
    C变量类型和作用域
    Java垃圾回收机制
    python 字符编码问题
    Linux文件和windows文件在 换行符的区别
    不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁
    Iterator和ListIterator
  • 原文地址:https://www.cnblogs.com/-maybe/p/4233339.html
Copyright © 2011-2022 走看看