树的重心-java

主要通过深度优先搜索来完成树的重心,其中关于树的重心的定义可以结合文字多加理解。

文章目录

前言☀

一、树的重心☀

二、算法思路☀

1.图用邻接表存储

2.图的遍历

3.算法思路 

二、代码如下☀

1.代码如下:

2.读入数据

3,代码运行结果

总结


前言☀

主要通过深度优先搜索来完成树的重心,其中关于树的重心的定义可以结合文字多加理解。


提示:以下是本篇文章正文内容,下面案例可供参考

一、树的重心☀

给定一颗树,树中包含 n 个结点(编号 1∼n)和 n−1 条无向边。

请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中结点数的最大值最小,那么这个节点被称为树的重心。

输入格式

第一行包含整数 n,表示树的结点数。

接下来 n−1行,每行包含两个整数 a 和 b,表示点 a 和点 b 之间存在一条边。

输出格式

输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值。

数据范围

1≤n≤100000

二、算法思路☀

1.图用邻接表存储

我们通过一个链表数组来存储,我们把数组中每一个链表的起点对应图中的一个结点,然后与该结点相连的结点,挂在数组中对应起始结点的后面即可,图示如下:

图1.1图邻接表存储 

我们引入一维整型数组e,存储链表里面的各个结点的值;一维整型数组ne里面存储结点的下一个结点在数组e里面的索引值;整型变量index表示新创建结点在e数组中的下标。

一位整型数组head用来存储图中的每个节点,head[i]表示以i结点为起点的单链表的头结点,链表中的每一个结点都是与i相连的结点,如图1.1所示。故head数组里面的值初始化为-1,表示此时链表都为空。

我们新创建的结点值为b即e[index] = b;然后将新创建的结点头插法插入,即将原本头结点后的所有结点链接到新结点后面即ne[index] = head[a];然后再将头结点指向新创建的结点head[a] = index。注意让index++,保证index一直指向新创建的结点。

    //添加边
    //头插法
    public static void add(int a,int b){
        e[index] = b;
        ne[index] = head[a];
        head[a] = index++;
    }

关于单链表的基本操作还有不明白的可以去看我的单链表-java-CSDN博客 这篇博客,里面有对单链表操作的各种详细介绍。

2.图的遍历

无向图是特殊的有向图,树也是特殊的图,故我们只需要考虑有向图即可。 

 

图2.1深度优先遍历示例图 

深度优先遍历其实就是一条路走到尽头,每当我们走过一个结点会设置一个标记表示已经走过了。当我们走到尽头无法再走时就回退到上一个结点,然后从该结点看看有无其它没走过的路径,无路可走时再回退到上一个结点,所有结点都被走过后就完成了深度优先遍历。依次走过的结点顺序如图2.1的黄色数字描述的顺序一致。

 

图2.2广度优先遍历示例图

 广度优先遍历也叫层序遍历,我们一层一层逐层遍历。可以通过队列模拟,将根结点入队;当队列不为空,弹出结点,然后再将与该结点相连的结点一次入队,重复上述操作,直到队列为空,就遍历的所有的结点。

遍历的顺序如图2.2模拟所示,黄色数字表示层数。

3.算法思路 

 图3.1样例模拟

图3.2删除结点1连通块情况 

图3.3删除结点2连通块情况 

图3.4删除结点4各个连通块情况 

树的重心:删除一个结点后,剩下的连通块中结点个数最多但是在删除各个结点的连通块中的结点数最小的,那么这个结点就是树的重心。通过上述图3.1-3.4的示例,即我们删除1结点连通块中结点最多是4,删除结点2连通块中结点最多是6,删除结点4连通块中结点最多是5,等等,我们可以知道结点1就是树的重心。

图3.5示例图 

 我们用深度优先搜索dfs来确定根节点u的结点的个数;当前结点遍历过设置为flag[u] = true;然后用整型变量sum来统计结点的个数,初始化为1(根节点本身),然后访问与u相连的边,如果没有被访问过,就接着对该边进行dfs深度优先搜索,然后更新为删除这一节点后所剩的连通图的结点数目的最大值;将sum加上子树的结点个数就是以u为根节点的结点的个数。

比较删除u后的u子树中最大的连通块(6,3-9中的更大者),和整个树减u子树剩下的连通块(1-2-8-5-7)
 res = Math.max(n - sum,res)。

sum:表示以这一点为根结点的树中所有结点个数
res:表示删除这一点后的连通块中结点数目的最大值(不断更新)
ans:表示所有(依次删除每个结点的情况)最大连通结点数目的最小值,即各个res的最小值(不断更新)
所有备注可结合上方图示一起看

    //深度优先搜索
    //以u为根节点的结点的个数
    public static int dfs(int u){
        //当前点被搜过了
        flag[u] = true;
        //存储以u为结点
        int sum = 1;
        //存储当前删掉某个结点后最大连通子图的个数
        int res = 0;
        //访问u的子节点
        for(int i = head[u];i != -1;i = ne[i]){
            int j = e[i];
            if(!flag[j]){
                int s = dfs(j);
                res = Math.max(s,res);
                //以u为根结点的树结点数量=1+它各个子树的结点数量
                sum += s;
            }
        }
        // 比较删除u后的u子树中最大的连通块(6,3-9中的更大者),和整个树减u子树剩下的连通块(1-2-8-5-7)
        res = Math.max(n - sum,res);
        //所有最大的连通块结点数目找到最小值
        ans = Math.min(ans,res);
        return sum;
    }

二、代码如下☀

1.代码如下:


import java.io.*;
import java.util.Arrays;
import java.util.Scanner;

public class 树的重心 {
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int N = 100010,M = N * 2;
    //记录头结点
    static int[] head = new int[N];
    //存储结点的值
    static int[] e = new int[M];
    //存储当前结点的下一个结点的索引值
    static int[] ne = new int[M];
    //最新创建的结点的索引即数组e中空最新的空结点的索引
    static int index;
    //用来存储结点是否被遍历过了
    static boolean[] flag = new boolean[N];
    static int n;

    static int ans = N;
    public static void main(String[] args) {
        Scanner sc = new Scanner(br);
        n = sc.nextInt();
        Arrays.fill(head,-1);
        for (int i = 0;i < n - 1;i++){
            int a = sc.nextInt();
            int b = sc.nextInt();
            add(a,b);
            add(b,a);
        }
        dfs(1);
        pw.print(ans);
        pw.flush();
    }
    //深度优先搜索
    //以u为根节点的结点的个数
    public static int dfs(int u){
        //当前点被搜过了
        flag[u] = true;
        //存储以u为结点
        int sum = 1;
        //存储当前删掉某个结点后最大连通子图的个数
        int res = 0;
        //访问u的子节点
        for(int i = head[u];i != -1;i = ne[i]){
            int j = e[i];
            if(!flag[j]){
                int s = dfs(j);
                res = Math.max(s,res);
                //以u为根结点的树结点数量=1+它各个子树的结点数量
                sum += s;
            }
        }
        res = Math.max(n - sum,res);
        //所有最大的连通块结点数目找到最小值
        ans = Math.min(ans,res);
        return sum;
    }
    //添加边
    public static void add(int a,int b){
        e[index] = b;
        ne[index] = head[a];
        head[a] = index++;
    }
}

2.读入数据

9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6

3,代码运行结果

4

总结

这次多看一下图示,理解各变量的意义,代码是简介,其中的意思要多加理解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【中间件系列】浅析redis是否适合做消息队列

文章目录 一、简单的list消息队列1.命令示例2.伪代码示例3.方案优劣 二、Pub/Sub发布订阅1.消息丢失2.消息堆积 三、相对成熟的Stream1.redis命令介绍2.多消费者组测试3.Stream会持久化吗&#xff1f;4.消息堆积如何解决&#xff1f; 总结 用redis也是比较久了&#xff0c;并且…

AI数据分析:用deepseek根据Excel数据绘制分裂饼形图

工作任务&#xff1a;要绘制下面表格中月活用户占比的分裂饼形图 在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本编写的任务&#xff0c;具体步骤如下&#xff1a; 读取Excel文件"F:\AI自媒体内容\AI行业数据分析\poetop5…

保姆级教程:以SAR图像目标检测为例

一、项目出发点 AI Studio为我们提供了免费的GPU资源&#xff0c;当我们在NoteBook环境中把代码调试成功后&#xff0c;通常一个训练任务耗时较长&#xff0c;而Notebook离线运行有时长限制&#xff0c;一不小心就容易被kill掉。 如何解决这一问题&#xff1f; 后台任务帮到…

探索智慧农业系统架构的设计与应用

随着科技的不断进步和农业现代化的推进&#xff0c;智慧农业正逐渐成为农业发展的重要趋势。智慧农业系统架构的设计与应用&#xff0c;将农业生产与信息技术相结合&#xff0c;为农业生产提供了新的思路和解决方案。本文将深入探讨智慧农业系统架构的设计与应用&#xff0c;从…

2021JSP普及组第二题:插入排序

2021JSP普及组第二题 题目&#xff1a; 思路&#xff1a; 题目要求排序后根据操作进行对应操作。 操作一需要显示某位置数据排序后的位置&#xff0c;所以需要定义结构体数组储存原数据的位置和数据本身排序后所得数据要根据原位置输出排序后的位置&#xff0c;所以建立一个新…

android中调用onnxruntime框架

创建空白项目 安装Android Studio及创建空白项目参考&#xff1a;【安卓Java原生开发学习记录】一、安卓开发环境的搭建与HelloWorld&#xff08;详细图文解释&#xff09;_安卓原生开发-CSDN博客 切记&#xff1a;build configuration language 一定选择Groovy&#xff01;官…

mysql报错 Duplicate entry

在MySQL中&#xff0c;当你尝试执行插入&#xff08;INSERT&#xff09;或更新&#xff08;UPDATE&#xff09;操作时&#xff0c;如果目标表中存在唯一索引&#xff08;包括主键索引、唯一约束索引等&#xff09;&#xff0c;并且你要插入或更新的数据在该索引列上的值与表中已…

电机控制系列模块解析(28)—— 其他功能概述

其他功能概述 软件侧&#xff1a;观测器估计发散保护、时序异常检测 主电路侧&#xff1a;IGBT结温估算、直流母线电容容值估算 电机侧&#xff1a;电机温度估计、轴承异常估计、电机退磁检测 负载侧&#xff1a;负载不平衡检测、掉载检测、负载惯量自适应 上述各项功能&a…

Diffusers代码学习: IP-Adapter Inpainting

IP-Adapter还可以通过Inpainting自动管道和蒙图方式生成目标图片。 # 以下代码为程序运行进行设置&#xff0c;使用Inpainting 的自动管道&#xff0c; import os os.environ["HF_ENDPOINT"] "https://hf-mirror.com"from diffusers import AutoPipelin…

【React】vscode 中 React 自动补齐标签设置

1.打开设置 2.搜索 includeLanguages 3. 在Emmet 下&#xff0c;点击“添加项”&#xff0c;添加一项 javascript --> javascriptreact 4. 重启vs code

学习笔记——路由网络基础——汇总静态路由

4、汇总静态路由 (1)定义 静态路由汇总&#xff1a;多条静态路由都使用相同的送出接口或下一跳 IP 地址。(将多条路由汇总成一条路由表示) (2)目的 1.减少路由条目数量&#xff0c;减小路由表&#xff0c;加快查表速度 2.增加网络稳定性 (3)路由黑洞以及路由环路的产生…

循环语句大揭秘:while、do-while、for、foreach你都掌握了吗?

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

idm2024最新完美破解版免费下载 idm绿色直装版注册机免费分享 idm永久激活码工具

IDM 2024破解版重新开发了调度程序和MMS协议支持、重新设计和增强的下载引擎、与所有最新浏览器的独特高级集成、改进的工具栏以及大量其他改进和新功能&#xff0c;这一全新的更新&#xff0c;使得IDM下载器更加完美。值得一提的是&#xff0c;它可以借助油猴浏览器的脚本&…

GAN网络理论和实验(二)

文章目录 一、说明二、什么是生成对抗网络&#xff1f;三、判别模型与生成模型四、生成对抗网络的架构五、你的第一个 GAN六、准备训练数据七、实现鉴别器八、实现生成器九、训练模型十、检查 GAN 生成的样本十一、使用 GAN 生成手写数字十二、准备训练数据十三、实现鉴别器和生…

【机器学习】XGBoost: 强化学习与梯度提升的杰作

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 XGBoost: 强化学习与梯度提升的杰作引言1. XGBoost概览1.1 什么是XGBoost&#…

玄机平台应急响应—apache日志分析

1、前言 apache的日志一共有两个&#xff0c;一个是access.log&#xff0c;这个日志记录了所有对Web服务器的访问&#xff0c;被入侵时重点排查这个。另一个是error.log&#xff0c;错误日志记录了服务器运行期间遇到的各种错误&#xff0c;以及一些普通的诊断信息&#xff0c…

Java——IO流(一)-(1/8):File、IO流概述、File文件对象的创建(介绍、实例演示)

目录 File IO流概述 File文件对象的创建 介绍 实例演示 File 存储数据的方案 变量 double money 9999.5 数组 int[] age new int[100];对象 Student s new Student()集合 List<Student> students new ArrayList<>()…

NIST 电子病历中的疾病列表部分的认证

美国国家标准与技术研究院&#xff08;National Institute of Standards and Technology&#xff0c;NIST&#xff09;对电子病历的认证 分几个阶段&#xff0c;每个阶段又分门诊和住院&#xff0c;然后又分若干模块。下面是疾病列表的测试脚本。 170.302c_Problemlist Test …

Maven中的DependencyManagement和Dependencies

Maven中的DependencyManagement和Dependencies Dependencies Dependencies是Maven项目中用来声明项目依赖的部分。在pom.xml文件中的<dependencies>部分&#xff0c;你可以直接列出项目所依赖的库&#xff08;artifacts&#xff09;。每个依赖通常包括以下信息&#xf…

DevExpress winForm gridView 设置复选框并可多选

OptionsSelection.MultiSelect True OptionsSelection.MultiSelectMode CheckBoxRowSelect