zoukankan      html  css  js  c++  java
  • 图论之最小生成树

    • prim算法

        基本思想:先从无向图中标记若干顶点,再从标记顶点中选择权值最小的边,且这条边的另一顶点未被标记,直到所有的点都已被标记。

        算法实现:用数组vis表示点的标记情况,数组low表示与点关联的最小权值情况。  

     1 int prim(int n)
     2 {
     3     int i,j;
     4     int min,pos;
     5     int ans=0;
     6 
     7     vis[0]=1; pos=0;
     8 
     9     for(i=0; i<n; i++)
    10         if(i!=pos) low[i]=dis[pos][i];
    11 
    12     for(i=0; i<n; i++)//n-1次循环
    13     {
    14         min = MaxInt;
    15         for(j=0; j<n; j++)
    16             if(vis[j]==0 && min>low[j])
    17             {
    18                 min=low[j];
    19                 pos=j;
    20             }
    21 
    22             ans+=min;
    23             vis[pos]=1;
    24 
    25         for(j=0; j<n; j++)
    26             if(vis[j]==0 && low[j]>dis[pos][j])//更新最小权值
    27                 low[j]=dis[pos][j];
    28     }
    29     return ans;
    30 }
    • kruskal算法 

        基本思想:对于无向图中所有的边,每次从当前为选择的边中选择权值最小且不会与已被选择的边构成环的边,直到所有的点都被标记,其中判断所选边是否构成环可以采用并查集来实现。

        算法实现:用数组pre来记录并查集中点的根节点的情况

    typedef struct edge
    {
        int a;
        int b;
        int value;
    };
    edge map[MAX];
    int pre[MAX];
    
    void init()//并查集初始化
    {
        for(int i=0; i<=MAX; i++)
            pre[i]=i;
    }
    
    int find(int x)//查找x的根节点并对路径进行压缩
    {
        int r=x;
        while(pre[r]!=r)//r=pre[r]表示r为根节点
            r=pre[r];
    
        //路径压缩
        int j,i=x;
        while(i!=r)
        {
            j=pre[i];
            pre[i]=r;
            i=j;
        }
    
        return r;
    }
    
    bool join(int x,int y)//判断是否成环
    {
        int root1=find(x);
        int root2=find(y);
    
        if(root1==root2) return false;
    
        pre[root1]=root2;//合并
        return true;
    }
    
    int kruskal()
    {
        int i=0,a,b;
        int ans=0;
        int num=1;
    
        while(num<n)
        {
            a=map[i].a;
            b=map[i].b;
            if(join(a,b))
            {
                ans+=map[i].value;
                num++;
            }
            i++;
        }
        return ans;
    }

      

  • 相关阅读:
    2020软件工程作业05
    一、uart&tty驱动
    柔性数组使用备忘
    指针和数组备忘
    计算信息帧的校验和(备忘)
    Linux系统vim几个常见配置
    C语言实现过滤ASCII在0~127范围内的字符,并去除重复的字符
    extern "C"的用法
    strtol详解
    将一个十进制整数转换为二进制并输出
  • 原文地址:https://www.cnblogs.com/leeshine/p/4316927.html
Copyright © 2011-2022 走看看