贪心算法:最小生成树

news2025/5/14 20:52:08

假设无向图为:

A-B:1

A-C:3

B-C:1

B-D:4

C-D:1

C-E:5

D-E:6

一、使用Prim算法:

public class Prim {
    //声明了两个静态常量,用于辅助 Prim 算法的实现
    private static final int V = 5;//点数
    private static final int INF = Integer.MAX_VALUE;//若直接使用 0 表示无边,会与边权为 0 的情况冲突。而 Integer.MAX_VALUE 是一个极大的值,在比较边权时不会被误认为有效边权。

    public static void main(String[] args){
        int [][] graph = new int[][]{
                {0, 1, 3, 0, 0},
                {1, 0, 1, 4, 0},
                {3, 1, 0, 1, 5},
                {0, 4, 1, 0, 6},
                {0, 0, 5, 6, 0}
        };//用二维数组表示无向图

        primMST(graph);
    }

    private static void primMST(int[][] graph) {
        int[] parent = new int[V];//记录每个结点的父节点
        int[] key = new int[V];//记录每个结点当前最小边权
        boolean[] mstSet = new boolean[V];//标记顶点是否已被加入MST

        for(int i =0;i<V;i++){
            key[i] = INF;
            mstSet[i] = false;
        }//初始化
        key[0] = 0;
        parent[0] = -1;
        //初始化
        for(int count =0;count<V-1;count++){
            int u = minKey(key,mstSet);//从未加入 MST 的顶点中选择 key 值最小的顶点 u
            mstSet[u] = true;//将 u 加入 MST
//遍历所有与 u 相邻的顶点 v:
//如果 v 未被加入 MST 且边 (u, v) 的权值小于 v 的当前 key,则更新 v 的 key 和 parent。
            for(int v=0;v<V;v++){
                if(graph[u][v] != 0&&mstSet[v]==false&&graph[u][v] < key[v]){
                    parent[v] = u;
                    key[v] = graph[u][v];
                }
            }
        }
        printMST(parent,graph);
    }
//打印结果
    private static void printMST(int[] parent, int[][] graph) {
        System.out.println("Edge \tWeight");
        for (int i = 1; i < V; i++) {
            System.out.println(parent[i] + " - " + i + "\t" + graph[i][parent[i]]);
        }
    }

    private static int minKey(int[] key, boolean[] mstSet) {
        int min = INF,minIndex = -1;
        //初始化
        for(int v = 0;v<V;v++){
            if(mstSet[v]==false && key[v]<min){
                min = key [v];
                minIndex = v;
            }
        }
        return minIndex;
    }

}

二、使用Kruskal算法:

import java.util.*;

public class Kruskal{
    private static final int V = 5; // Number of vertices in the graph
    private Edge[] edges; // 存储所有边,包含三个成员变量:src(源顶点)、dest(目标顶点)和 weight(边的权重)。
    private int edgeCount = 0; // 边的数量

    class Edge implements Comparable<Edge> {
        int src, dest, weight;

        public int compareTo(Edge compareEdge) {
            return this.weight - compareEdge.weight;
        }
    }
//用于实现并查集
    class subset {
        //用于跟踪每个顶点的父节点和秩
        int parent, rank;
    }
//查找顶点 i 的根节点,并实现路径压缩
    int find(subset[] subsets, int i) {
        if (subsets[i].parent != i) {
            subsets[i].parent = find(subsets, subsets[i].parent);
        }
        return subsets[i].parent;
    }
//合并两个子集,使用秩来保持树的平衡
    void Union(subset[] subsets, int x, int y) {
        int xroot = find(subsets, x);
        int yroot = find(subsets, y);

        if (subsets[xroot].rank < subsets[yroot].rank) {
            subsets[xroot].parent = yroot;
        } else if (subsets[xroot].rank > subsets[yroot].rank) {
            subsets[yroot].parent = xroot;
        } else {
            subsets[yroot].parent = xroot;
            subsets[xroot].rank++;
        }
    }

    public static void main(String[] args) {
        int[][] graph = new int[][]{
                {0, 1, 3, 0, 0},
                {1, 0, 1, 4, 0},
                {3, 1, 0, 1, 5},
                {0, 4, 1, 0, 6},
                {0, 0, 5, 6, 0}
        };

        Kruskal kruskal = new Kruskal();
        kruskal.kruskalMST(graph);
    }

    void kruskalMST(int[][] graph) {
        // 计算边的数量并初始化edges数组
        int edgeCount = 0;
        //初始化
        for (int i = 0; i < V; i++) {
            for (int j = i + 1; j < V; j++) {
                if (graph[i][j] != 0) {
                    edgeCount++;
                }
            }
        }
        edges = new Edge[edgeCount];
        edgeCount = 0;

        // 初始化边数组
        for (int i = 0; i < V; i++) {
            for (int j = i + 1; j < V; j++) {
                if (graph[i][j] != 0) {
                    edges[edgeCount] = new Edge();
                    edges[edgeCount].src = i;
                    edges[edgeCount].dest = j;
                    edges[edgeCount].weight = graph[i][j];
                    edgeCount++;
                }
            }
        }

        // 步骤1: 按权重升序排列边
        Arrays.sort(edges);

        // 步骤2: 初始化子集
        subset[] subsets = new subset[V];
        for (int i = 0; i < V; i++) {
            subsets[i] = new subset();
            subsets[i].parent = i;
            subsets[i].rank = 0;
        }

        // 步骤3: 用于存储MST的边
        Edge[] result = new Edge[V - 1];
        int e = 0; // 结果数组的索引
        int i = 0; // 排序后边的索引

        // 步骤4: 遍历每条边并添加到MST中(如果不形成环)
        while (e < V - 1 && i < edges.length) {
            Edge next_edge = edges[i++];

            int x = find(subsets, next_edge.src);
            int y = find(subsets, next_edge.dest);

            if (x != y) {
                result[e++] = next_edge;
                Union(subsets, x, y);
            }
        }

        // 输出结果
        System.out.println("Following are the edges in the constructed MST");
        for (i = 0; i < e; i++) {
            System.out.println(result[i].src + " -- " + result[i].dest + " == " + result[i].weight);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2375620.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp-文件查找失败:‘@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue‘

uniapp-文件查找失败&#xff1a;‘dcloudio/uni-ui/lib/uni-icons/uni-icons.vue’ 今天在HBuilderX中使用uniapp开发微信小程序时遇到了这个问题&#xff0c;就是找不到uni-ui组件 当时创建项目&#xff0c;选择了一个中间带的底部带选项卡模板&#xff0c;并没有选择内置u…

Vue2.x 和 Vue3.x 对比-差异

Vue3的优点 diff算法的提升 vue2中的虚拟DOM是全量的对比&#xff0c;也就是不管是写死的还是动态节点都会一层层比较&#xff0c;浪费时间在静态节点上。 vue3新增静态标记&#xff08;patchflag &#xff09;&#xff0c;与之前虚拟节点对比&#xff0c;只对比带有patch fla…

MacOS 用brew 安装、配置、启动Redis

MacOS 用brew 安装、配置、启动Redis 一、安装 brew install redis 二、启动 brew services start redis 三、用命令行检测 set name tom get name

agentmain对业务的影响

前面一篇已经说了java agent技术主要有premain和agentmain两种形式&#xff0c;如果大部分业务已经在线上运行的话&#xff0c;不方便用premain的方式来实现&#xff0c;所以agentmain的方式是更加通用、灵活的 由于RASP是与用户业务运行在同一个jvm中的 &#xff0c;所以RASP…

uniapp小程序轮播图高度自适应优化详解

在微信小程序开发过程中&#xff0c;轮播图组件(swiper)是常用的UI元素&#xff0c;但在实际应用中经常遇到高度不匹配导致的空白问题。本文详细记录了一次轮播图高度优化的完整过程&#xff0c;特别是针对固定宽高比图片的精确适配方案。 问题背景 在开发"零工市场&quo…

基于ESP32控制的机器人摄像头车

DIY Wi-Fi 控制的机器人摄像头车&#xff1a;从零开始的智能探索之旅 在当今科技飞速发展的时代&#xff0c;机器人技术已经逐渐走进了我们的生活。今天&#xff0c;我将带你一起探索如何制作一个 Wi-Fi 控制的机器人摄像头车&#xff0c;它不仅可以远程操控&#xff0c;还能通…

基于STM32的LCD信号波形和FFT频谱显示

一、项目准备 主要利用LCD驱动中的画点和画连线函数&#xff0c;驱动是正点原子给我写好了的画点和画线的函数等些相关函数 void LCD_Draw_Circle(u16 x0,u16 y0,u8 r); //画圆 void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2); //画线 二、画波形图函数实…

(9)被宏 QT_DEPRECATED_VERSION_X_6_0(“提示内容“) 修饰的函数,在 Qt6 中使用时,会被编译器提示该函数已过时

&#xff08;1&#xff09;起因是看到 Qt 的官方源代码里有这样的写法&#xff1a; #if QT_DEPRECATED_SINCE(6, 0) //里面的都是废弃的成员函数QT_WARNING_PUSHQT_WARNING_DISABLE_DEPRECATEDQT_DEPRECATED_VERSION_X_6_0("Use the constructor taking a QMetaType inst…

关于mac配置hdc(鸿蒙)

关于mac配置hdc(鸿蒙) 在最开始配置的hdc -v时候老是出现格式不匹配 于是乎在网上找官网也不行&#xff0c;最后在csdn上找到了这篇文章Mac配置hdc才有的头绪 环境变量的问题 自己做一个简单的总结 首先在访达里面打开ide 打开之后输入下面的命令&#xff0c;一步一步的找…

是 OpenCV 的 CUDA 模块中用于在 GPU 上对图像或矩阵进行转置操作函数cv::cuda::transpose

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::transpose 是 OpenCV 的 CUDA 模块中的一个函数&#xff0c;用于在 GPU 上对图像或矩阵进行转置操作&#xff08;Transpose&#xff0…

PPT图表怎么制作?说5款自己使用过的PPT图表制作工具

PPT图表怎么制作&#xff1f;准备一份吸引人的PPT演示文稿时&#xff0c;图表往往能起到画龙点睛的作用。但是&#xff0c;对于很多人来说&#xff0c;制作既美观又专业的图表却不是一件容易的事情。今天&#xff0c;我们就来聊聊如何利用一些优秀的工具制作PPT图表。 1、亿图图…

[传输层]TCP协议

文章目录 报文格式连接管理可靠传输 面向连接的传输层协议 每一条TCP连接只能有两个端点&#xff0c;每一条TCP连接只能是点对点的 TCP提供可靠有序&#xff0c;不丢不重 TCP是面向字节流的 TCP工作模型&#xff1a; 发送方有一个缓存&#xff0c;缓存&#xff1a; 1.待发送 2…

Linux(1)编译链接和gcc

1、gcc分布编译链接 &#xff08;1&#xff09;预编译 gcc -E main.c -o main.i &#xff08;2&#xff09;编译 gcc -S main.i -o main.s &#xff08;3&#xff09;汇编 gcc -c main.s -o main.o &#xff08;4&#xff09;链接 gcc main.o -o main 执行&#xff1a…

【Java ee初阶】网络编程 UDP socket

网络编程 socket api 是传输层提供的api。 UDP 无连接&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工。 TCP 有链接&#xff0c;可靠传输&#xff0c;面向字节流&#xff0c;全双工。 UDP socket api 数据报 DatagrammSocket 代表了操作系统中的socket文…

旅游推荐数据分析可视化系统算法

旅游推荐数据分析可视化系统算法 本文档详细介绍了旅游推荐数据分析可视化系统中使用的各种算法&#xff0c;包括推荐算法、数据分析算法和可视化算法。 目录 推荐算法 基于用户的协同过滤推荐基于浏览历史的推荐主题推荐算法 亲子游推荐算法文化游推荐算法自然风光推荐算法…

c语言第一个小游戏:贪吃蛇小游戏08(贪吃蛇完结)

贪吃蛇撞墙和想不开咬死自己 #include <curses.h> #include <stdlib.h> struct snake{ int hang; int lie; struct snake *next; }; struct snake food; struct snake *head; struct snake *tail; int key; int dir; #define UP 1 #define DOWN -1 …

使用PhpStudy搭建Web测试服务器

一、安装PhpStudy 从以下目录下载PhpStudy安装文件 Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 安装成功之后打开如下界面 点击启动Apache 查看网站地址 在浏览器中输入localhost:88,出现如下页面就ok了 二、与Unity交互 1.配置下载文件路径&#xff0c;点击…

c语言第一个小游戏:贪吃蛇小游戏06

实现贪吃蛇四方向的风骚走位 实现代码 #include <curses.h> #include <stdlib.h> struct snake{ int hang; int lie; struct snake *next; }; struct snake *head; struct snake *tail; int key; int dir; //全局变量 #define UP 1 //这个是宏定义&a…

Qt应用程序启动时的一些思路:从单实例到性能优化的处理方案

程序启动时优化的价值 在桌面软件开发领域&#xff0c;应用程序的启动过程就像音乐的序曲&#xff0c;决定了用户对软件品质的第一印象。比如首次启动等待超过3秒时&#xff0c;会让大多数用户产生负面看法&#xff0c;而专业工具软件的容忍阈值甚至更低。Qt框架作为跨平台开发…

一文详解Spring Boot如何配置日志

一、写在前面 对于日志文件&#xff0c;相信大家都并不陌生&#xff0c;通过在关键位置打印相关的日志&#xff0c;有利于快速跟踪和定位软件系统运行中存在的问题。 在之前的 Java 实现日志记录的文章中&#xff0c;我们介绍了能实现日志记录的主流框架有 Log4j、Log4j2、Lo…