zoukankan      html  css  js  c++  java
  • Kruskal 算法——并查集

    需要注意的地方 :将所有的边权从小到大依次排序,按从小到大依次加入边,每次对加入的边进行如下操作:

    1.找出边的两点。

    2.判断两点的父亲节点是在同一个集合里。

    3.如果不在同一个集合,在将两点所在的集合合并 :Union,且计数器+1;

    5.当计数器=n-1(总点数)时 ,停止查找。此时只有一个集合,该集合即为最小生成树。

    ps.最大生成树的方法与之相同。

    用并查集可以很方便保存边~


    c++代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct Edge{
     int x;
     int y;
     int v;
    }a[100001];
    int father[100001],n,m,num_edge,k,tot;
    int cmp(const Edge &a,const Edge &b)
    {
     if(a.v<b.v) return 1;
     else return 0;
    }
    int find_father(int x)
    {
     if(x!=father[x]) father[x]=find_father(father[x]);
     return father[x];
    }
    int Unionn(int x,int y)
    {
     int fa=find_father(x);
     int fb=find_father(y);
     if(fa!=fb)
     {
      father[fa]=fb;
     }
    }
    int main()
    {
     cin>>m>>n;
     for (int i=1;i<=n;i++)
     {
      int x,y,v;
      cin>>x>>y>>v;
      a[++num_edge].x=x;a[num_edge].y=y;a[num_edge].v=v;
      a[++num_edge].x=y;a[num_edge].y=x;a[num_edge].v=v;
     }
     sort(a+1,a+1+num_edge,cmp);
     for (int i=1;i<=num_edge;i++) father[i]=i;
     for (int i=1;i<=num_edge;i++)
     {
      if(find_father(a[i].x)!=find_father(a[i].y))
      {
       Unionn(a[i].x,a[i].y);
       k++;
       tot+=a[i].v;
      } 
      if(k==n-1) break;
     }
     cout<<tot;
     
        return 0;
    }

  • 相关阅读:
    Linux 下基础命令
    jquery
    系统运维
    jmeter响应断言
    测试方案和测试报告、需求变更控制
    Fiddler抓包12-AutoResponder返回本地数据(mock)
    Fiddler抓包11-HTTPS证书Actions无法导出问题
    Fiddler抓包10-会话框添加查看get与post请求类型
    Fiddler抓包9-保存会话(save)
    Fiddler抓包8-打断点(bpu)
  • 原文地址:https://www.cnblogs.com/ffhy/p/5661726.html
Copyright © 2011-2022 走看看