C++树形dp经验总结(换根dp,点覆盖问题,含例题City Upgrading)

文章介绍了树形动态规划(树形dp)的概念,重点讨论了两种常见问题类型:换根dp和点覆盖问题。换根dp常用于求解以哪个节点为根时树的某种属性最大,而点覆盖问题则是寻找最少节点数以覆盖树的所有边。文章提供了相应的代码示例和解题思路。

最近几天一直在看树形dp的相关问题,并写了几道经典的模板例题,这里来稍微总结一下树形dp。

首先顾名思义,树形dp就是指题意要求,在树形的结构上的动态规划问题,转移方程通常就是从树的父节点和子节点之间进行转移,所以核心的状态转移部分是在dfs深度搜索中实现,下面是两个常见的树形dp问题类型。

一是换根dp,这个说是树形dp的类型,倒不如说是树形dp的具体方法的一种,通常见于求树上某个结点的什么属性要最大,然后这个属性又需要我们从这个结点出发遍历一次树才能得到。从暴力的角度思考,枚举每个结点并搜索一次,复杂度就是O(n²),一般是会超时的(如果题目是想你用树形dp做的话),这时候我们就得考虑用树形dp,也就是如何用一次搜索的结果,来得到每个结点的对应答案。

经典的例题比如STA-Station,求一棵树中,以哪个结点作为根,其他所有结点的深度之和最大。单独一个点的深度之和用dfs或者bfs一下就很容易可以得到,但是想要求以哪个结点为根得到的答案最大,没法枚举每一个结点都跑一遍搜索。但是我们可以通过记录结点的一些信息,来递推得到这个结果。需要记录的信息包括,以初始的某个结点为根跑完dfs后,每个结点的深度,每个结点的子树的大小(包括本身的结点个数),以及以该结点为根时的其他结点深度和。具体的推导过程就不放这了,大概可以自己试着推推看,核心利用根从父节点变为子节点时,原先子节点的子树的深度统统减一,父节点的其他子树的深度加一,利用这个关系可以得到递推式。然后再跑一遍dfs,从父节点开始向子节点不断更新答案数组。下面放放我的代码:

#include<bits/stdc++.h>
#include<queue>
#define db double
#define ll long long
#define ui unsigned int
using namespace std;
const int maxn = 1e6+10;
vector<int>G[maxn];
ll dep[maxn],size[maxn],f[maxn],n;
int read() {
	int x = 0, f = 0, ch = getchar();
	while (!isdigit(ch)) { if (ch == '-')f = 1;ch = getchar(); }
	while (isdigit(ch)) { x = x * 10 + ch - '0';ch = getchar(); }
	return f ? -x : x;
}
void dfs1(int u,int fa){
	for(auto v:G[u]){
		if(v==fa)continue;
		dep[v]=dep[u]+1;
		dfs1(v,u);
		size[u]+=size[v];
		f[u]+=f[v];
	}
	size[u]++;
	f[u]+=dep[u];
}
void dfs2(int u,int fa){
	for(auto v:G[u]){
		if(v==fa)continue;
		f[v]=n-2*size[v]+f[u];
		dfs2(v,u);
	}
}
in
<think> 我们无法用一段简短的代码覆盖Python所有知识,因为Python语言包的内容非常广泛(基础语法、数据结构、函数、面向对象、模块、异常处理、文件操作、并发编程等)。但我们可以尝试编写一个综合示例,尽可能多地展示Python的核心概念。 以下代码示例将展示: 1. 变量和基本数据类型 2. 条件语句和循环 3. 列表、元组、字典、集合 4. 函数定义和使用 5. 类与对象(面向对象编程) 6. 异常处理 7. 文件读写 8. 模块导入 9. 生成器和装饰器(高级特性) 10. 上下文管理器(with语句) 11. 并发编程(简单示例) 注意:由于篇幅和复杂度限制,每个知识仅做简单演示。 我们将编写一个示例,包一个学生成绩管理系统的简单模型。 </think> 以下是一段综合性的Python代码示例,覆盖了原生Python的核心知识(Python 3.8+),包注释说明: ```python # ===== 基础语法 ===== # 1. 变量与数据类型 name = "Python" # 字符串 version = 3.9 # 整数 is_awesome = True # 布尔值 pi = 3.14159 # 浮数 nothing = None # 空值 # 2. 数据结构 nums_list = [1, 2, 3, 4, 5] # 列表(可变序列) nums_tuple = (1, 2, 3) # 元组(不可变序列) user_dict = {"name": "Alice", "age": 25} # 字典(键值对) unique_nums = {1, 2, 3, 3, 4} # 集合(去重) → {1,2,3,4} # 3. 控制流 # 条件语句 if version > 3 and is_awesome: print(f"{name} {version} is awesome!") elif version < 3: print("Consider upgrading") else: print("Standard version") # 循环语句 for i in range(3): # range迭代 print(f"Count: {i}") while version > 0: # while循环 print(version) version -= 1 if version == 0: break # 循环中断 # ===== 函数 ===== # 4. 函数定义 def calculate_area(radius: float) -> float: # 类型提示 """计算圆面积 (文档字符串)""" global pi # 全局变量 return pi * radius ** 2 # 5. 高阶函数 squares = list(map(lambda x: x**2, nums_list)) # lambda表达式 & map even_nums = [x for x in nums_list if x%2==0] # 列表推导式 # ===== 面向对象 ===== # 6. 类与继承 class Animal: def __init__(self, species: str): # 构造器 self.species = species def speak(self) -> str: raise NotImplementedError("Subclasses must implement") class Dog(Animal): # 继承 def speak(self): # 方法重写 return "Woof!" def __str__(self): # 魔术方法 return f"{self.species} dog" # 7. 实例化 buddy = Dog("Canine") print(buddy.speak()) # ===== 高级特性 ===== # 8. 异常处理 try: result = 10 / 0 except ZeroDivisionError as e: # 异常捕获 print(f"Error: {e}") finally: # 清理操作 print("Execution completed") # 9. 上下文管理器 (文件操作) with open("example.txt", "w") as f: # 自动关闭文件 f.write("Hello Context Manager!") # 10. 装饰器 def logger(func): def wrapper(*args, **kwargs): # 参数解包 print(f"Calling {func.__name__}") return func(*args, **kwargs) return wrapper @logger def add(a, b): return a + b # 11. 生成器 def fibonacci(n: int): a, b = 0, 1 for _ in range(n): yield a # yield关键字 a, b = b, a + b # ===== 模块管理 ===== # 12. 导入模块 import math # 标准库导入 from datetime import datetime as dt # 别名导入 print(math.sqrt(16)) print(dt.now()) if __name__ == "__main__": # 主程序入口 print(add(2, 3)) print(list(fibonacci(5))) ``` ### 覆盖的知识清单 1. **基础语法**:变量、数据类型、运算符 2. **数据结构**:列表/元组/字典/集合操作 3. **控制流**:`if-elif-else`/`for`/`while`/`break` 4. **函数**:定义/参数/返回值/`lambda`/作用域 5. **函数式编程**:`map`/列表推导式 6. **面向对象**:类定义/继承/魔术方法/实例化 7. **异常处理**:`try-except-finally` 8. **文件操作**:上下文管理器(`with`) 9. **高级特性**:装饰器/生成器(`yield`) 10. **模块系统**:导入机制/`__name__`主模块判断 11. **类型系统**:类型提示(Type Hints) 12. **字符串操作**:f-string格式化 > 提示:Python知识体系庞大,实际项目还需掌握: > - 包管理(`pip`/`virtualenv`) > - 并发编程(`threading`/`asyncio`) > - 标准库深度使用(`collections`/`itertools`等) > - 元编程(元类/描述符) ### 学习建议 1. 通过官方文档深入每个知识 [^1] 2. 使用`coverage`工具检测代码覆盖率 [^2] 3. 实践项目驱动学习(如Web开发/数据分析)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值