C++ dfs 与图有关的知识(四十七)【第七篇】

news/2024/7/20 22:14:14 标签: 深度优先, 算法

今天我们接着来学习树上搜索(dfs深度优先搜索)

1.树的深度与子树大小

树的深度:规定根结点是树的第一层,树根的孩子结点是树的第二层,以此类推,树的深度就是结点的最大层数。

根据定义,如果我们已经知道树中某个结点 u 的深度 dep[u],那么结点 
u 的儿子结点 
v 的深度 dep[v]=dep[u]+1。

图片

求解每个结点的深度:自上而下。

int dep[110];
void dfs(int u, int fa) {
    dep[u] = dep[fa] + 1;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v != fa) {
            dfs(v, u);
        }
    }
}

在树上有一个很重要的概念是子树,子树就是包括当前节点和它底下所有节点的一棵树。

比如

图片

如果以 
1 为根,那么以 2 号结点为根的子树就包括 2,4,6 三个点,这棵子树大小就是 3 。

这一节我们就来求解以每个点为根的子树的大小。

解决子树问题,往往是把一棵子树拆成子树的根和底下的很多棵小的子树。

图片

比如这里,如果 
1 是整棵树的根,那么以 2 为根的子树,可以拆成 2 (子树根),6,7,8(以 6 为根的子树),4(以 4 为根的子树),三部分,这三部分的点数加起来就是这棵子树的大小。

所以一个子树可以拆成子树根(一个节点)和每一棵以它的孩子为根的子树,所以这棵子树的大小就是所有以它的孩子为根的子树的大小的和再加 1。

接下来我们来研究如何通过代码解决这样的问题,对于当前节点来讲我们需要让它先搜索它的所有子节点,得到这些子节点的子树的大小,加起来再加 11 。

首先我们需要一个数组sz记录以每个点为根的子树的大小。

然后我们可以把搜索的dfs函数返回值改为int类型,返回以当前节点u为根的子树的大小。这样我们在找每一个与当前节点u相连的子节点v的时候,把到v去搜索得到的返回值加进sz[u]上,这样就把以u的每个子节点为根的子树的大小都加进来了,最后再给sz[u]加上 11(u节点本身),返回就可以了。

代码就是这样

​​​​​​​
int sz[110];
int dfs(int u, int fa) {
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (v != fa) {
            sz[u] += dfs(v, u);
        }
    }
    sz[u]++;
    return sz[u];
}
 
 

求解每棵子树的大小:自下而上。

如果大家把搜索过程画出来,把dfs序写出来会发现,一棵子树一定是在dfs序上一段连续的序列,这一点是dfs序一个非常好的性质,也是dfs序最有用的性质。

比如

图片

这棵树,以 1 为根,一种dfs序就是 1,2,6,7,8,4,3,5 ,会发现以每个点为根的子树都对应了这个dfs序的连续一段。

这个也是因为dfs本身就需要把当前点以下的所有点都搜完了才会返回到上一层的点。


http://www.niftyadmin.cn/n/5364859.html

相关文章

AIGC实战——归一化流模型(Normalizing Flow Model)

AIGC实战——归一化流模型 0. 前言1. 归一化流模型1.1 归一化流模型基本原理1.2 变量变换1.3 雅可比行列式1.4 变量变换方程 2. RealNVP2.1 Two Moons 数据集2.2 耦合层2.3 通过耦合层传递数据2.4 堆叠耦合层2.5 训练 RealNVP 模型 3. RealNVP 模型分析4. 其他归一化流模型4.1 …

【Linux】进程间通信 --管道通信

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0. 进程间通信原理1. 匿名管道1.1 通信原理1.2 接口介绍 2. 命名管道2.1 接口介绍 3. 共享内存3.1 通信原理3.2 接口介绍 0. 进…

console.log导致内存泄露 打包时自动去掉console.log方法

webpack通过工具&#xff1a;terser 使用前需要先安装一下 vue.config.js const { defineConfig } require(vue/cli-servise); module.exports defineConfig({transpileDependencies:true,terser:{terserOptions:{compress:{drop_console:true,drop_debugger:true,},},},}…

XCTF:warmup[WriteUP]

CtrlU查看页面源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible&q…

CAP原则、网络分区

升级版点这里 CAP原则&#xff0c;也称为CAP定理&#xff0c;是在设计分布式系统时必须考虑的三个基本需求。 1.一致性&#xff08;Consistency&#xff09;:在分布式系统中的所有数据备份&#xff0c;在同一时刻是否为同样的值。【所有节点访问同一份最新的数据副本】 2.可用…

nginx slice模块的使用和源码分析

文章目录 1. 为什么需要ngx_http_slice_module2. 配置指令3. 加载模块4. 源码分析4.1 指令分析4.2 模块初始化4.3 slice模块的上下文4.2 $slice_range字段值获取4.3 http header过滤处理4.4 http body过滤处理5 测试和验证 1. 为什么需要ngx_http_slice_module 顾名思义&#…

【2023地理设计组一等奖】城市业态基因图谱与城市风格感知

作品介绍 1 设计思路 1.1 作品背景 随着城市化进程不断推进,城市的餐饮、购物、休闲和文化业态成为城市发展中的重要组成部分,深刻影响着城市经济社会发展和居民生活,塑造了城市的外在形象和内在风格,形成了各具特色的城市发展特征。因此,在区域和全国尺度上研究城市业态…

两次NAT

两次NAT即Twice NAT&#xff0c;指源IP和目的IP同时转换&#xff0c;该技术应用于内部网络主机地址与外部网络上主机地址重叠的情况。 如图所示&#xff0c;两次NAT转换的过程如下: 内网Host A要访问地址重叠的外部网络Host B&#xff0c;Host A向位于外部网络的DNS服务器发送…