Kruskal

Prim算法用来处理稠密图,Kruskal算法来处理稀疏图。

大致思路:

先用结构体对该的边以及点进行储存,然后根据每条边的权重来进行升序排序,
取权重最小的边放入所要维护的树中:如果该条边不在区域中才会将其放入区域中(所要维护的树中)。判断是否在区域中的方法即是:运用并查集的查找函数,用于找到顶点x所在的集合的代表元素,如果根节点相同,那么就在同一片区域中(所要维护的树中)

伪代码:

for(int i=0;i<m;i++)
{
  if(find(a)!=find(b))
{
p[find(a)]=find(b);
对应的其它条件
}

}

代码:

/*
①将所有边按权重从小到大排序
②枚举每条边a,b权重c
  if(a,b不连通的话)
   将这条边加入集合当中去
*/

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=1e5+10;
//ans表示最小生成树的权值,cnt表示最小生成树的边数(若要表示点数,cnt的初始值应该=1)
int n,m,cnt,ans;
int p[N];

struct Edge
{
    int a,b,w;
//重载运算符,使得该结构体可以以边的权重来排序
    bool operator< (const Edge &W)const
    {
        return w<W.w;
    }
}edge[N*2];

/*
寻找该点的祖宗节点(这是并查集里的板子)
并查集的查找函数,用于找到顶点x所在的集合的代表元素,并进行路径压缩。
*/
int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

void kruskal()
{
    for(int i=0;i<m;i++)
    {
        //取出每条边对应的点以及权值
        int a=edge[i].a,b=edge[i].b,c=edge[i].w;
        //如果两点不在同一区域上的话
        /*
        如果此时在同一区域上,则会有两种可能:①:已经放入区域了,不需要重复放入
        ②:将此点放入区域后恰好使区域形成环(也就是①的特例)
        */
        if(find(a)!=find(b))
        {
            //置为同一区域
            p[find(a)]=find(b);
            //对应区域的权值增加
            ans+=c;
            //区域边数增加
            cnt++;
        }
    }
    
    //n个点对应n-1条边
    if(cnt<n-1) cout << "impossible";
    else cout << ans;
}

int main()
{
    cin >> n >> m;
    
    //初始化并查集
    for(int i=1;i<=n;i++) p[i]=i;
    
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin >> a >> b >> c;
        edge[i]={a,b,c};
    }
    //排序,对边的权值进行排序
    sort(edge,edge+m);
    
    kruskal();
    
    return 0;
}

重载运算符:

若想比较边的权重:

bool operator< (const Edge &W) const
{
    return w<W.w;
}
//上述Edge表示结构体名,W表示重载结构体

 若想比较点的大小:

struct Edge {
    int a, b, w;
    
    // 重载<运算符,首先按照a升序排序,如果a相同,则按照b升序排序
    bool operator< (const Edge &W)const {
        if (a == W.a) {
            return b < W.b;
        }
        return a < W.a;
    }
};

在这个重载的运算符中,我们首先比较两个边的第一个点a。如果a相同,我们再比较第二个点b。这样,当我们对Edge类型的数组使用sort函数时,它会首先按照a进行升序排序,如果a相同,则按照b进行升序排序。

若想进行降序:

struct Edge {
    int a, b, w;
    
    // 重载<运算符,首先按照a升序排序,如果a相同,则按照b降序排序
    bool operator< (const Edge &W)const {
        if (a == W.a) {
            return b > W.b; // 注意这里改为>,表示降序
        }
        return a < W.a;
    }
};

 

此外:

在C++中,当你重载一个成员函数(比如运算符)时,通常你会看到&符号,这代表函数的引用调用。对于重载的运算符,使用&可以避免不必要的复制,尤其是在处理较大的结构体时。

相关推荐

  1. Kruskal

    2024-07-11 05:20:03       23 阅读
  2. 生成树-Kruskal & Prim

    2024-07-11 05:20:03       29 阅读
  3. 详解 Kruskal 算法的实现

    2024-07-11 05:20:03       51 阅读
  4. Kruskal算法刷题笔记

    2024-07-11 05:20:03       28 阅读
  5. 最小生成树 prim + kruskal

    2024-07-11 05:20:03       41 阅读
  6. 最小生成树——Prim/Kruskal Python

    2024-07-11 05:20:03       49 阅读
  7. 算法基础之Kruskal算法求最小生成树

    2024-07-11 05:20:03       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 05:20:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 05:20:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 05:20:03       58 阅读
  4. Python语言-面向对象

    2024-07-11 05:20:03       69 阅读

热门阅读

  1. C++入门

    C++入门

    2024-07-11 05:20:03      20 阅读
  2. Spring框架配置进阶_自动装配(XML和注解)

    2024-07-11 05:20:03       20 阅读
  3. xml CDATA

    2024-07-11 05:20:03       23 阅读
  4. XML Schema 杂项数据类型

    2024-07-11 05:20:03       24 阅读
  5. 我的前端实习之旅

    2024-07-11 05:20:03       22 阅读
  6. 算法——二分法

    2024-07-11 05:20:03       26 阅读
  7. Python 简介

    2024-07-11 05:20:03       25 阅读
  8. 内核调试方法

    2024-07-11 05:20:03       22 阅读