最小生成树

最小生成树

算法简介

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。简言之就是在一个连通图中找出一些边使得所有节点联通。

算法描述

虽然有很多可以实现最小生成树的算法,我们只讨论Kruskal算法。

Kruskal(克鲁斯科尔算法)

该算法算是贪心算法的引用

步骤:

  • 新建图G,G中拥有原图中相同的节点,但没有边
  • 将原图中所有的边按权值从小到大排序
  • 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
  • 重复3,直至图G中所有的节点都在同一个连通分量中

代码描述

我们间接通过并查集来实现判断是否两个节点存在于同一个连通分量

int f[maxn];
int find(int u){
    if(u==f[u])return u;
    f[u]=find(f[u]);
    return f[u];
}
void join(int u,int v){
    int fu=find(u);
    int fv=find(v);
    if(fu!=fv){
        f[fu]=fv;
    }
}
struct edge{
    int from,to,cost;
    friend bool operator <(edge a,edge b){
        return a.cost<b.cost;
    }
}Ed[maxn];
int V,E;
int kruskal(){
    sort(Ed,Ed+E);
    iniuni(V);
    int res=0;
    for(int i=0;i<E;i++){
        edge e=Ed[i];
        int fu=find(Ed[i].from);
        int fv=find(Ed[i].to);
        if(fu!=fv){
            join(e.from,e.to);
            res+=e.cost;
        }
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值