资讯专栏INFORMATION COLUMN

【图论】最小生成树

?xiaoxiao, / 1856人阅读

摘要:最小生成树有两种生成算法普里姆算法克鲁斯克尔算法算法普利姆算法算法流程我的理解任选一个元素,作为起始点将起始点标记为,代表该点已经加入最小生成树集合计算这个集合到未加入的各个点的距离选择一个最小的距离点,加入集合,即标记为已访问更新集合到其

最小生成树有两种生成算法

Prim(普里姆算法)

Kruskal(克鲁斯克尔)算法

Prim 算法(普利姆算法)

算法流程:(我的理解)

任选一个元素,作为起始点

将起始点标记为visit,代表该点已经加入最小生成树集合

计算这个集合到未加入的各个点的距离

选择一个最小的距离点,加入集合,即标记为已访问

更新集合到其他各个点的最小距离

迭代

存疑

- 目前没有找到记录下路径的办法,不知道是不是还没理解到位
Java 实现
package com.edu.chapter03;

import org.junit.Test;

public class MinimumTree {
    /**
     * 最小生成树
     */
    int n;
    int e[][];
    int dis[];

    public void createMinmumTree() {
        int pos = 1; // 从1节点开始,可以任意指定;pos 代表当前要加入最小生成树集合的编号
        int join[] = new int[n + 1]; // 记录各个点加入的情况
        int weight = 0;
        // 初始化最小生成树集合与其他各个点的距离
        for (int i = 1; i <= n; i++) {
            dis[i] = i == pos ? 0 : e[pos][i];
        }

        for (int i = 2; i <= n; i++) { // 从寻找第二个点开始(并不是代表要把2号点添加进去)
            int min = Integer.MAX_VALUE;
            for (int j = 1; j <= n; j++) {
                if (join[j] == 0 && dis[j] !=0 && min > dis[j]) { // 找出集合距离未加入的点的最近边及点;dis[j]!=0 表示跳过和自己的比较
                    min = dis[j];
                    pos = j; // 找到最小位置,下一个要加入的点就是这个点
                }
            }

            join[pos] = 1; // 标记为以加入最小生成树集合
            weight += min;
 
            //重新计算集合距离其他点的距离
            for (int j = 1; j <= n; j++) {
                if (join[j] == 0 && dis[j] > e[pos][j]) { // 比较新加入的点是否带来的更短的距离,
                    dis[j] = e[pos][j]; //有,则更新。保证dis里存储的是到其他点的最近距离
                }
            }
        }
        System.out.println("weight:" + weight);
    }

    @Test
    public void test01() {
        n = 6;
        e = new int[n + 1][n + 1];
        dis = new int[n + 1];

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (i == j) {
                    e[i][j] = 0;
                } else {
                    e[i][j] = Integer.MAX_VALUE;
                }
            }
        }

        e[1][2] = e[2][1] = 2;
        e[1][3] = e[3][1] = 4;
        e[1][4] = e[4][1] = 7;

        e[2][3] = e[3][2] = 1;
        e[2][5] = e[5][2] = 2;

        e[3][4] = e[4][3] = 1;
        e[3][5] = e[5][3] = 6;
        createMinmumTree();
    }
}
Kruskal(克鲁斯克尔)算法

算法思路

首先将图中的边按权重大小排序(从小到大)

可以使用快速排序或者堆排序

取出一条边,将边对应的两个节点放入一个集合

如果集合中已经存在这两个点,则放弃该边

不断有边加入,将不同的集合连起来,直到集合包含了所有节点,结束

每次有效添加的一条边,代表了最小生成树中对应的边,或者说路径

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71310.html

相关文章

  • leetcode310. Minimum Height Trees

    摘要:现在要求在这样一棵生成树中,找到生成树的高度最低的所有根节点。然后利用邻接表的相关属性来判断当前节点是否是叶节点。度数为一的顶点就是叶节点。这里使用异或的原因是对同一个值进行两次异或即可以回到最初值。 题目 For an undirected graph with tree characteristics, we can choose any node as the root. The...

    xiaoxiaozi 评论0 收藏0
  • Python猫荐书系列:文也深度学习,理也深度学习

    摘要:本期猫荐书栏目系列之六,就以此为话题,推荐给大家两本书它们都叫深度学习,但是内容很不一样。事实上,第一本书被很多人誉为深度学习的圣经,知名度极高,有一个昵称叫作花书。 最近出了两件大新闻,相信大家可能有所耳闻。 我来当个播报员,给大家转述一下: 1、中国队在第 11 界罗马尼亚数学大师赛(RMM)中无缘金牌。该项赛事是三大国际赛事之一,被誉为中学奥数的最高难度。其中一道题,令中国队全军...

    LuDongWei 评论0 收藏0

发表评论

0条评论

?xiaoxiao,

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<