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;

    }

  • 相关阅读:
    LeetCode 27. Remove Element(C++)
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 21. Merge Two Sorted Lists(c++)
    LeetCode 20. Valid Parentheses(c++)
    LeetCode 14.Longest Common Prefix(C++)
    poj1847 Tram(最短路dijkstra)
    poj 3268 Silver Cow Party(最短路dijkstra)
    LeetCode 13. Roman to Integer(c语言版)
    hdu2181 简单搜索
    python 算法 day1
  • 原文地址:https://www.cnblogs.com/-maybe/p/4233339.html
Copyright © 2011-2022 走看看