Kruskal算法(最小生成树)

Posted zdl2234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kruskal算法(最小生成树)相关的知识,希望对你有一定的参考价值。

Kruskal算法:首先按照边的权值进行从小到大排序,每次从剩余的边中选择权值最小的边且不会产生回路的边加入到生成树中,直到加入n-1条边就结束;

算法难点在与如何判断是否会产生回路。这个可以通过并查集实现,将所有加入生成树的结点加入同一个集合;

代码:

#include <string.h>
#include<iostream>
#include<vector>
#include<queue>
#include <algorithm>
using namespace std;
struct edge{//边的结构
    int u;
    int v;
    int w;
}e[100];
int f[100];//并查集数组
bool compare(struct edge a,struct edge b){//sort函数的比较器,实现边权从小到达排序
    return a.w<=b.w;
}
int getF(int x){//查找结点的根
    if(f[x]==x) return x;
    else {
        f[x]=getF(f[x]);//直接连接到根结点,实现路径压缩
        return f[x];
    }
}
bool unity(int a,int b){//联合所有加入生成树的结点
    int f1=getF(a);
    int f2=getF(b);
    if(f1!=f2){
        f[f1]=f2;
        return true;
    }
    return false;
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){//输入边信息
        cin>>e[i].u>>e[i].v>>e[i].w;
    }
    for(int i=0;i<100;i++){//初始化并查集
        f[i]=i;
    }
    sort(e,e+m,compare);//排序
    int munber=0,sum=0;
    for(int i=0;i<m;i++){//从小到大检测每一个结点是否可以加入生成树
        if(unity(e[i].u,e[i].v)){
            munber++;
            sum+=e[i].w;
        }
        if(munber==n-1) break;//当加入n-1条边,就可以结束
    }
    cout<<sum<<endl;
    return 0;
}

 

以上是关于Kruskal算法(最小生成树)的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树详解 prim+ kruskal代码模板

(最小生成树)Kruskal算法

最小生成树及Prim算法及Kruskal算法的代码实现

最小生成树算法:Kruskal算法 Prim算法

最小生成树

图解:如何实现最小生成树(Prim算法与Kruskal算法)