• 最小生成树 克鲁斯卡尔(Kruskal)算法求最小生成树


    Kruskal算法的过程:
    (1) 将全部边按照权值由小到大排序。 (2) 按顺序(边权由小到大的顺序)考虑没条边,只要这条边和我们已经选择的边步构成圈,就保留这条边,否则放弃这条边。
    算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通。
    图中的路径按照权值的大小的排序为
    AF 1;
    BE 4;
    BD 5;
    BC 6;
    DC:10;
    BF 11;
    DF 14;
    AE 16;
    AB 17;
    EF 33;
    算法的处理过程如下
    先选A,F不在一个集合中,所以选AF。
    E,D不在一个一个集合中,可以选
     
    B,D不在一个集合中,可选BD
    B,C不在一个集合中,可选BC
    B,D在同一个集合中,放弃BD,
    选BF
    至此所有的的顶点都连起来,算法结束= =
     
     
    ;u[i],v[i]分别储存顶点,w[i]保存权值,用r[i]表示边的序号
    这里对权值的排序可以这样写
    1 bool cmp(int i,int j)
    2 {
    3     return w[i]<w[j];
    4 }
    5 sort(r,r+m,cmp);

    然后我们需要考虑新加入的边会不会和先前选好的边形成环,即判断u,v,是否在同一连通分量中,这里我们用并查集来查找,然后合并
    f[x]表示x的,合并只需条语句f[x]=y;。然后实现实现克鲁斯卡尔的算法的代码如下

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 #define maxn 5000
     7 int f[maxn];
     8 int u[maxn],v[maxn],w[maxn],r[maxn];
     9 int n,m;
    10 bool cmp(int i,int j)
    11 {
    12     return w[i]<w[j];
    13 }
    14 int find(int x)
    15 {
    16     return f[x]==x?x:find(f[x]);
    17 }
    18 __int64 Kruskal()
    19 {
    20     __int64 ans=0;
    21     for(int i=1;i<=n;i++)
    22     {
    23         f[i]=i;
    24     }
    25     for(int i=1;i<=m;i++)
    26     {
    27         r[i]=i;
    28     }
    29     sort(r+1,r+m+1,cmp);
    30     for(int i=1;i<=m;i++)
    31     {
    32         int e=r[i];
    33         int x=find(u[e]);
    34         int y=find(v[e]);
    35         if(x!=y)
    36         {
    37             ans+=w[e];
    38             f[x]=y;
    39         }
    40     }
    41     return ans;
    42 }
    43 int main()
    44 {
    45     while(~scanf("%d",&n)&&n)
    46     {
    47         memset(r,0,sizeof(r));
    48         //memset(u,0,sizeof(u))
    49         m=n*(n-1)/2;
    50     for(int i=1;i<=m;i++)
    51     {
    52         scanf("%d %d %d",&u[i],&v[i],&w[i]);
    53     }
    54     printf("%lld
    ",Kruskal());
    55 }
    56 }
     
  • 相关阅读:
    TensorFlow学习笔记1:graph、session和op
    TensorFlow学习笔记2:逻辑回归实现手写字符识别
    Tensorflow学习笔记3:卷积神经网络实现手写字符识别
    Firstpython介绍
    Oracle sql语句学习
    总结__window dns域名解析错误及其解决方法
    Group By 和 Having, Where ,Order by语句的执行顺序
    Oracle 语句分类
    webbrowser自动登录,没有点击事件,不是submit提交按钮的情况下如何模拟点击登录
    webbrowser跨域访问iframe中的元素实现自动登录
  • 原文地址:https://www.cnblogs.com/NaCl/p/4705570.html
Copyright © 2020-2023  润新知