zoukankan      html  css  js  c++  java
  • Kruskal算法

    Kruskal算法(克鲁斯卡尔算法)

    核心操作
    1、将所有边按权重大小 从小到大排序 O(mlogm); 这部分是本算法的瓶颈 比较耗时
    2、 枚举每条边a -b 权重为c
    如果 a-b 不连通 则把这条边加入集合中
    (因为最小生成树不能含有自环,如果a-b已经连通,再加入这条边就会形成自环)

    并查集的操作来维护本算法

    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100010, M = 200010, INF = 0x3f3f3f3f;
    
    int n, m;
    int p[N];
    
    struct Edge
    {
        int a, b, w;
    
        /* bool operator< (const Edge &W)const
         {
            return w < W.w;
         }*/
        Edge() {
    
            a = 0;
            b = 0;        //注意 ,当写了有参构造函数时,一定要加上无参构造函数,不然会编译出错
            w = 0;
    
        }
        Edge(int aa, int bb, int ww) {
            a = aa;
            b = bb;
            w = ww;
        }
    
    }edges[M];
    
    bool operator<(Edge A, Edge B) {
    
        return A.w < B.w;          //重载运算符 使用sort排序时一般重载小于号
    }
    
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]); //并查集中的find函数
        return p[x];                    // 如果x不是祖宗节点 则继续找祖宗节点 否则返回祖宗节点
    }
    
    int kruskal()
    {
        sort(edges+1, edges + m+1);//注意 数组为1~m排序时  sort正常是0~n
    
        for (int i = 1; i <= n; i++) p[i] = i;    // 初始化并查集
    
        int res = 0, cnt = 0;
        for (int i = 1; i <=m; i++)
        {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
    
            a = find(a), b = find(b);//找到a b的祖宗节点
            if (a != b)//如果祖宗节点不同 则说明他们不连通
            {
                p[a] = b; //将他们合并成一个集合
                res += w;//累加边的权重值
                cnt++;//更新集合中已经有的边数
            }
        }
    
        if (cnt < n - 1) return INF;//n个点 一共有n-1 条边 如果最后集合中的边数小于n-1 则说明不能连通
        return res;// 图可以连通 返回边权和
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
    
        for (int i = 1; i <=m; i++)  //结构体无向图初始化方法 本体按有向图初始化不影响最小生成树
        {
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            edges[i] = Edge(a, b, w);
    
        }
    
        int t = kruskal();
    
        if (t == INF) puts("impossible");
        else printf("%d
    ", t);
    
        return 0;
    }
    
    你以为的极限,也许只是别人的起点
  • 相关阅读:
    关于http请求头的一些事
    关于http抓取字段的一些事
    多线程的一些事
    正则的一些事
    出现问题集及解决方案
    常见的正则
    Http常见状态码
    list&tuple简记
    函数式编程--高阶函数--sorted
    函数式编程--高阶函数--filter
  • 原文地址:https://www.cnblogs.com/LengDing/p/14296866.html
Copyright © 2011-2022 走看看