最小生成树——Kruskal算法

这篇具有很好参考价值的文章主要介绍了最小生成树——Kruskal算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

基本思想

实现

伪代码

实际问题求解


最小生成树:带权连通图的生成树中 边的权值之和最小的生成树。

  • 最小生成树不是唯一的。当图中的各边权值互不相等时,最小生成树是唯一的;
  • 若无向连通图本身是一棵树时(边数比顶点数少1 ),则最小生成树就是它本身。
  • 最小生成树的边数为顶点数减1。

基本思想

(找权值最小的边)

  1. 初始时为只有n 个顶点而无边的非连通图 T 每个顶点自成一个连通分量,然后按照边的权值由小到大的顺序;
  2. 不断选取当前未被选取过且权值最小的边,若该边依附的顶点落在 T 中不同的连通分量上,则将此边加入 T , 否则舍弃此边而选择下一条权值最小的边。以此类推,直至T中所有顶点都在一个连通分量上。

最小生成树——Kruskal算法

  •  通常在Kruskal算法中,采用堆来存放边的集合,因此每次选择最小权值的边只需的时间。此外,由于生成树中的所有边可视为一个等价类,因此每次添加新的边的过程类似于求解等价类的过程,由此可以采用并查集的数据结构来描述从而构造广的时间复杂度为。(|E|表示边数)
  • Kruskal算法适合于边稀疏而顶点较多的图。

实现

伪代码

void Kruskal(V,T) {
    T=V;  			//初始化树,仅含顶点
    numS=n; 		//连通分量数
    while(numS>l){	//若连通分量数大于1
        从E中取出权值最小的边(v,u); 
        if(v和 u 属于T 中不同的连通分量){ 
            T=TU{ (v,u) };//将此边加入生成树中
            numS-; 		//连通分量数减1
        }
    }
}

实际问题求解

 P1546 [USACO3.1]最短网络 Agri-Net

题目背景:Farmer John 被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。

题目描述:FJ 已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过。

(采用基本Kruskal算法求解:Prim算法求解见http://t.csdn.cn/OFNwt)文章来源地址https://www.toymoban.com/news/detail-425408.html

public class MST {
    class Edge{
        int x,y,wei;
        public Edge(int x,int y,int wei){
            this.x=x;
            this.y=y;
            this.wei=wei;
        }
    }
    //并查集
    class UFSets{
        private int[] vex;
        public UFSets(int n){
            vex=new int[n];
            for (int i = 0; i < n; i++) {
                vex[i]=i;
            }
        }
        //x的最高祖宗
        public int find (int x){
           return vex[x]==x?x:find(vex[x]);
        }
        //合并
        public void union (int x,int y){
            int fx=find(x);
            int fy=find(y);
            if (fx!=fy){
                vex[fx]=fy;
            }
        }
    }
    public int kruskal(int[][] w){
        int n=w.length;
        //最小生成树总权值
        int result=0;
        //顶点集初始化
        UFSets vex=new UFSets(n);
        List<Edge> list=new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                if (w[i][j]>0){
                    list.add(new Edge(i,j,w[i][j]));
                }
            }
        }
        list.sort(new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.wei-o2.wei;
            }
        });
        //选n个边
        for (Edge e : list) {
            if (n<=0){
                break;
            }
            //边的两个点属于不同连通分量,则加入这条边
            if (vex.find(e.x)!=vex.find(e.y)){
                vex.union(e.x,e.y);
                result+=e.wei;
                n--;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt();
        int[][] w=new int[n][n];
        for (int i = 0; i < w.length; i++) {
            for (int j = 0; j < w.length; j++) {
                w[i][j]=scan.nextInt();
            }
        }
        System.out.println(new MST().kruskal(w));
    }
}

到了这里,关于最小生成树——Kruskal算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最小生成树——Kruskal算法详解

    1.Kruskal算法解决问题 :最小生成树 2.Kruskal所需要的前提知识: 边集数组(引用)和 结构体 3.Kruskal算法主要思想: Kruskal算法将 n 个点看成 n 个独立的连通分支。 首先按边权大小排序。 然后只要在 m 条边里按 下表从小到大遍历 选出 合适 的 n - 1 条(前提条件:选出的边不

    2024年02月03日
    浏览(31)
  • Kruskal算法求解最小生成树

    最小生成树是一个连通图。 什么是连通图,(强)连通图详解 前面介绍了《图存储结构》,本节继续讲解什么是 连通图 。 前面讲过,图中从一个顶点到达另一顶点,若存在至少一条路径,则称这两个顶点是连通着的。例如图 1 中,虽然 V1 和 V3 http://c.biancheng.net/view/3405.ht

    2024年02月07日
    浏览(49)
  • 最小生成树(Prim算法,Kruskal算法)

    (1)生成树: 如果在一个无向连通图不包含回路(连通图中不存在环),则为一个树 (2)最小生成树(minimal spanning tree): 在一个图所有生成树中,代价最小的生成树称为最小生成树 (3)生成树的代价: 在一个无向连通网中,生成树各边的权值之和称为该生成树的代价

    2024年02月08日
    浏览(35)
  • 859. Kruskal算法求最小生成树

    给定一个 nn 个点 mm 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出  impossible 。 给定一张边带权的无向图 G=(V,E)G=(V,E),其中 VV 表示图中点的集合,EE 表示图中边的集合,n=|V|n=|V|,m=|E|m=|E|。 由

    2023年04月09日
    浏览(30)
  • 图的最小生成树-Kruskal算法

    目录 问题引入  程序设计  程序分析 本节文章 【问题描述】 编写程序,利用带权无向图的邻接矩阵存储,实现图的最小生成树Kruskal算法。

    2024年02月08日
    浏览(50)
  • 最小生成树—Kruskal算法和Prim算法

    连通图:在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中任 意一对顶点都是连通的,则称此图为连通图。 生成树:一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点 和n-1条边。 最小生成树:构成生成树的

    2024年02月05日
    浏览(36)
  • 最小生成树(Prim算法与Kruskal算法)

    一个连通图的生成树是一个极小的连通子图,它含有图中全部的n个顶点,但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树。 例如下图中①、②、③都是左侧图的生成树,但③是构造连通网的最小代价,所以③是该图的最小生成树。 P

    2024年02月05日
    浏览(49)
  • 最小生成树算法之Kruskal算法(c++)

    与Prim算法生成图的最小生成的树算法不同在于: Prim算法是基于图中的顶点的,且不依赖于边,Prim从顶点出发拓展,依次找每个顶点相邻的权值最小的边,直至生成最小生成树。因此,Prim算法的时间复杂度是O(v^2),适合边稠密图。 而Kruskal算法恰恰相反,是基于图中的边的一

    2024年02月12日
    浏览(33)
  • 图论13-最小生成树-Kruskal算法+Prim算法

    基本思想:按照权值从小到大的顺序选择 n-1 条边,并保证这 n-1 条边不构成回路 具体做法:首先构造一个只含 n 个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中 不产生 回路,直至森林变成一棵树为止。 2.2.1 如果图不联通,直接返回空,该

    2024年02月01日
    浏览(37)
  • 最小(代价)生成树—Prim算法与Kruskal算法

    目录  一、最小生成树的特点 二、最小生成树算法  ① Prim(普里姆)算法 ②Kruskal(克鲁斯卡尔)算法  ③Prim算法与Kruskal算法对比 最小生成树是带权连通图G=(V,E)的生成树中边的权值之和最小的那棵生成树。它具有以下特点: 图G中各边权值互不相等时有唯一的最小生成树。图

    2024年02月01日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包