• kruskal求最小生成树


    kruskal求最小生成树:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 100010;
    int p[N];
    struct Edge{
        int a, b, w;
        bool operator < (const Edge &W) const
        {
            return w < W.w;
        }
    }edges[N];
    int find(int x)
    {
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    int main()
    {
        int n, m;
        cin>>n>>m;
        for(int i = 0; i < m; i++)
        {
            int a, b, w;
            cin>>a>>b>>w;
            edges[i] = {a, b, w};
        }
        sort(edges,edges + m);
        for(int i = 1; i <= n; i++) p[i] = i;
        int res = 0, cnt = 0;
        for(int i = 0;i<m;i++)
        {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a), b = find(b);
            if(a != b)
            {
                p[a] = b; //两个不连通的点进行合并
                res += w;  //最小生成树边权之和,边数+1
                cnt++;
            }
        }
        if(cnt < n - 1) cout<<"impossible"<<endl;
        else cout<<res<<endl;
    }

    1、将所有的边从到达进行排序, sort(edges, edges + m);

    2、以此从小到大枚举每条边的两个点,如果两个点不在同一个集合当中(用并查集的祖先来判断 find(a) == find(b)),那么就进行合并 p[a] = b; 加入到集合当中来,累加边权,再统计边数cnt。

    如果最终通过Kruskal算法得出的最小生成树的边数cnt < n - 1那么就不符合最小生成树的定义,n个点和n - 1条边组成。

  • 相关阅读:
    几个数之和----数组刷题
    单调栈刷题
    腾讯金融科技凉经
    mysql刷题
    链表类题目常用方法
    阿里云一面凉经
    腾讯TEG一面凉经
    腾讯软件开发-后台开发实习生-一面凉经
    剑指 Offer 19. 正则表达式匹配
    剑指 Offer 20. 表示数值的字符串
  • 原文地址:https://www.cnblogs.com/longxue1991/p/12715016.html
Copyright © 2020-2023  润新知