最小生成树-Kruskal算法

1.定义

prime算法是按照点与点之间的最小权值逐次将点加入到生成树中,而Kruskal算法则是按照每条边的长度依次排序,将最短的边中对应的点加入到最小生成树中,最小生成树的用并查集来表示。

1.Kruskal算法是以 边 为基础,每次从 边 集合中寻找最小的边(不管两个顶点属于V还是Vnew),然后判断该边的两个顶点是否同源(属于同一个连通分量)。 2.Kruskal需要对所有的边进行排序,然后从小到大,依次遍历每条边,同时判断每条边是否同源,如果同源,跳过;如果不同源,将两个连通分量合并,直到所有顶点属于同一个连通分量,算法结束。

2.代码实现

class Solution {
 public:
     int minCostConnectPoints(vector<vector<int>>& points) {
         vector<vnode>vlist;
         for (int i = 0; i < points.size(); i++) {
             for (int j = i + 1; j < points.size(); j++) {
                 //把所有点和边的组合加入到vlist中
                 vlist.push_back({ i,j,abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]) });
             }
         }
		//按照边的最小序进行排序
         sort(vlist.begin(), vlist.end(), [](vnode a, vnode b) {
             return a.length < b.length;
         });

         
         ufs t(points.size());
         for (auto x : vlist) {
           
             t.merge(x.point1, x.point2, x.length);
             if (t.get_count() == 1) {
                 return t.get_length();
             }
         }
         return 0;
     }

     struct vnode {
         int point1;
         int point2;
         int length;
     };
     //并查集
     class ufs {
     public:
         ufs(int n):parent(vector<int>(n)),count(n),rank(vector<int>(n,0)) {
             for (int i = 0; i < parent.size(); i++) {
                 parent[i] = i;
             }
         }

         int find(int value){
             if (parent[value] != value) {
                 return find(parent[value]);
             }
             else {
                 return value;
             }
         }

         void merge(int point1,int point2,int length) {
             if (find(point1) != find(point2)) {
                 if (rank[point2] > rank[point1]) {
                     swap(point1, point2);
                 }
                 parent[find(point2)] = find(point1);

                 rank[point1]++;
                 count--;            
                 this->length += length;
                //  cout<<count<<" "<<length<<endl;

             }
         }

         int get_count() { return count; }
         int get_length() { return length; }
     private:
         vector<int>parent;
         vector<int>rank;
         int count;
         int length = 0;
     };
 };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值