蓝桥杯备战资料从0开始!!!(python B组)(最全面!最贴心!适合小白!蓝桥云课)基础的树上问题

注:你的关注,点赞,评论让我不停更新

1. 树的基本概念与表示

概念

树是一种无向无环的连通图,由节点和边组成。其中有一个特殊节点被称为根节点,除根节点外,每个节点都有一个父节点。节点到根节点的路径上经过的节点数量称为该节点的深度,树中节点的最大深度就是树的高度。

表示方法

在 Python 中,常用邻接表来表示树。例如:

# 假设有 5 个节点的树,节点编号从 0 到 4
n = 5
# 初始化邻接表
tree = [[] for _ in range(n)]
# 添加边 (0, 1)
tree[0].append(1)
tree[1].append(0)
# 添加边 (0, 2)
tree[0].append(2)
tree[2].append(0)
# 添加边 (1, 3)
tree[1].append(3)
tree[3].append(1)
# 添加边 (1, 4)
tree[1].append(4)
tree[4].append(1)

2. 树的遍历

深度优先搜索(DFS)
  • 原理:从根节点开始,沿着一条路径尽可能深地访问节点,直到无法继续,然后回溯到上一个节点,继续探索其他路径。

  • 应用场景:计算树的深度、路径和、子树节点数量等。

  • 示例代码

# 计算树的深度
def dfs(node, parent, tree, depth):
    max_depth = depth
    for child in tree[node]:
        if child != parent:
            max_depth = max(max_depth, dfs(child, node, tree, depth + 1))
    return max_depth
​
# 调用示例
root = 0
tree_depth = dfs(root, -1, tree, 0)
print("树的深度为:", tree_depth)
广度优先搜索(BFS)
  • 原理:从根节点开始,逐层地访问节点,先访问距离根节点近的节点。

  • 应用场景:求树的最短路径、层次遍历等。

  • 示例代码

from collections import deque
​
# 树的层次遍历
def bfs(root, tree):
    queue = deque([root])
    visited = [False] * len(tree)
    visited[root] = True
    result = []
    while queue:
        node = queue.popleft()
        result.append(node)
        for child in tree[node]:
            if not visited[child]:
                queue.append(child)
                visited[child] = True
    return result
​
# 调用示例
level_order = bfs(root, tree)
print("树的层次遍历结果为:", level_order)

3. 最近公共祖先(LCA)

概念

在树中,对于两个节点 uv,它们的最近公共祖先是指距离它们最近的共同祖先节点。

应用场景
  • 计算树上两点之间的距离:dist(u, v) = dist(u, root) + dist(v, root) - 2 * dist(lca(u, v), root)

  • 处理树上的路径查询问题。

示例代码(简单的暴力法)
# 查找节点的祖先节点
def find_ancestors(node, parent, tree, ancestors):
    ancestors.append(node)
    for child in tree[node]:
        if child != parent:
            find_ancestors(child, node, tree, ancestors)
​
# 查找最近公共祖先
def lca(u, v, tree):
    ancestors_u = []
    find_ancestors(u, -1, tree, ancestors_u)
    ancestors_v = []
    find_ancestors(v, -1, tree, ancestors_v)
    for node in ancestors_u:
        if node in ancestors_v:
            return node
​
# 调用示例
u = 3
v = 4
lca_node = lca(u, v, tree)
print(f"{u} 和 {v} 的最近公共祖先是:", lca_node)

4. 树的直径

概念

树的直径是指树中任意两个节点之间的最长路径的长度。

应用场景
  • 求树中最远的两个节点的距离,例如在一些地图问题中,求两个地点之间的最长距离。

示例代码
# 第一次 DFS,找到距离起始节点最远的节点
def dfs1(node, parent, tree, distance):
    max_dist = 0
    farthest_node = node
    for child in tree[node]:
        if child != parent:
            dist, far = dfs1(child, node, tree, distance + 1)
            if dist > max_dist:
                max_dist = dist
                farthest_node = far
    return max_dist + 1, farthest_node
​
# 第二次 DFS,计算树的直径
def tree_diameter(root, tree):
    _, farthest = dfs1(root, -1, tree, 0)
    diameter, _ = dfs1(farthest, -1, tree, 0)
    return diameter - 1
​
# 调用示例
diameter = tree_diameter(root, tree)
print("树的直径为:", diameter)

5. 树的重心

概念

树的重心是指树中的一个节点,当把这个节点删除后,剩余的各个子树中节点数量的最大值最小。

应用场景
  • 优化树的分治算法,选择重心作为分割点可以使子问题的规模更加均衡。

示例代码
# 计算树的重心
def find_centroid(node, parent, tree, n):
    global centroid, min_max_subtree
    size = 1
    max_subtree = 0
    for child in tree[node]:
        if child != parent:
            child_size = find_centroid(child, node, tree, n)
            size += child_size
            max_subtree = max(max_subtree, child_size)
    max_subtree = max(max_subtree, n - size)
    if max_subtree < min_max_subtree:
        min_max_subtree = max_subtree
        centroid = node
    return size
​
# 调用示例
n = len(tree)
centroid = -1
min_max_subtree = float('inf')
find_centroid(root, -1, tree, n)
print("树的重心为:", centroid)

这些基础的树上问题在蓝桥杯的题目中经常出现,你需要熟练掌握它们的原理和实现方法,并且多做相关的练习题来提高解题能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

手可摘星chen.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值