洛谷 P1122 最大子树和 题解

这篇具有很好参考价值的文章主要介绍了洛谷 P1122 最大子树和 题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一道入门的树形DP。

首先我们对于数据进行有序化处理,这便于我们利用数据结构特点(可排序性)来发觉数据性质(有序、单调、子问题等等性质),以便于后续的转化、推理和处理。有序化可以“转化和创造”性质

首先将视角从无根树切换为有根树,这样我们就可以得到一个带有最优子结构、无后效性、子问题重叠性的结构——一个根和一堆子树。

由于我们是要求联通分量的最大值,我们观察到每一个联通分量都可以看做一个有根树,这就保证了树形DP的正确性。(后面会再解释)

不难想到令\(f_i\)表示包含该位置的、以\(i\)号节点为根的子树的最大值。

这里的“不难想到”其实有两种想法——第一种是树形DP的一般思路就是子啊一棵子树内处理根与子树的关系,这是一种常见的经验或者说手法。第二种想法就是说,连通分量可以转化成更小的联通分量,加上有序化之后,变成了子树层层求解。

我们考虑每一棵子树,不难发现初始化每个节点就是根节点自己的值,然后对于每一棵向下连接根节点的子树的最大值,如果大于零,那么我们就把根通向这棵子树的边连接起来。

\(j\)\(i\)子树根节点的编号,有$f_i = \sum f_j \times [f_j > 0] $

关于正确性,可能会有问题:对于一棵子树而言,我们只考虑了这些向下的分支,并没有考虑向上父节点的这支“分支”,感觉不太对劲?

实际上,我们要明确我们这里求的是一个小范围内子问题的最优解,不是全局最优解。如果每个点都考虑所有的分支情况(包括向上找父亲的那个分支),那么所有的点都是在求全局最优解,这样就无法进行DP或者状态转移了, 问题也没有得到简化。

我们考虑所谓“向上”的分支,实际上就是上面“向下”的分支,所以这种情况显然是可以被覆盖到的。如果上面的向下伸的这个分支是断的,没有到达这个子树的根节点,那么这棵子树加上向上一段的分支最大也会是负的,显然单独的子树或者单独的上面那个点都是更优的,不会有贡献。

实际上,我们陷入这种思维泥潭的主要原因还是不清楚DP的逻辑——DP的局部最优解是为全局服务的,这个局部最优解是在某种定义下成立的,不代表全局最优,但是可以求出全局最优。就比如这道题里面的局部最优解就不包括向上的分支,它只考虑这一棵子树内的情况,这样保证了问题的规模从小到大,保证了其他可以DP的性质。

思考DP算法,某种意义上而言,是一种构建数学和逻辑的“自动机”的过程。

DP可以从经验出发,可以从DP性质出发, 也可以从问题本身的性质出发,三者相互联系,加上一些转化或者优化的技巧可以求解。

总结:树形DP的一种一般分析方法是有序化(有根树)后考虑子树上跟和子树的关系转移;可以从小规模子问题入手;定义一种可以转移的状态(意义),并确定初始值和转移方法;时刻清楚讨论的问题和环境是什么,比如在局部最优中讨论整体最优就是无太大意义的,因为DP中不需要考虑

一种步骤:转化、子问题、状态、转移方程、优化

要格外注意递归中的“回头找”和计算和的关系。在这里是,不能把判断vis放到开头,不但多递归一层,就会多计算一层和。

源码:文章来源地址https://www.toymoban.com/news/detail-581915.html


#include <bits/stdc++.h>

#define N (int)(16005)

using namespace std;

typedef long long LL;

LL a[N];

vector<int> e[N];

LL f[N];

LL ans;

bool vis[N];

void dfs(int p)
{
	ans = max(ans,f[p]);
	vis[p] = true;
	vis[p] = true;
	//cout << p << "\n";
	for(int i = 0;i < e[p].size();i++)
	{
		int q = e[p][i];
		if(vis[q]) continue;
		dfs(q);
		//cout << p << " " << q << " " << f[p] << " " << f[q] << "\n";
		if(f[q] > 0) f[p] += f[q];
		ans = max(ans,f[p]);
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int n;
	cin >> n;
	memset(f,0x8f,sizeof(f));
	memset(vis,0,sizeof(vis));
	ans = -1e18;
	for(int i = 1;i <= n;i++)
	{
		cin >> a[i];
		f[i] = a[i];
	}
	for(int i = 1;i <= n-1;i++)
	{
		int x,y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs(1);
	cout << ans << "\n";
	return 0;
}

到了这里,关于洛谷 P1122 最大子树和 题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二叉树 — 返回最大的二叉搜索子树大小

    题目: 给定一棵二叉树的head节点,返回这颗二叉树中最大的二叉搜索子树的大小。 一颗二叉树来讲,可能整棵树不是搜索二叉树,但子树是一颗搜索二叉树。如下图所示,这时要返回这颗子搜索二叉树的最大节点个数。下图中,最大的二叉搜索子树大小为:3(5 - 1 - 7)。

    2024年02月13日
    浏览(48)
  • C++---树形DP---树的最长路径(每日一道算法2023.5.4)

    注意事项: 本题为\\\"树与图的DFS深度优先遍历—树的重心\\\"的近似题,同时涉及到 单链表模拟邻接表存储图 的操作,建议先理解那篇文章。 题目: 给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。 现在请你找到树中的一条最长路径。 换句话

    2024年02月02日
    浏览(36)
  • 洛谷 P8742题解

    简单版(P2347)传送门 原题传送门 有一道 类似 的题目(P2347),先扯一扯~ 动态规划入门题(01背包 可行性问题 )~ 我们 设 (dp_j) 为能否用砝码称出 (j) 重量 ,1 为 可以 ,0 为 不可以 。 为了转移, (dp_{_{0}} gets 1) , 什么都不放时,重量为 0 ,因此可以称出。 那么 枚举

    2024年02月06日
    浏览(51)
  • 洛谷P1249题解

    一个正整数一般可以分为几个互不相同的自然数的和,如 3 = 1 + 2 3=1+2 3 = 1 + 2 , 4 = 1 + 3 4=1+3 4 = 1 + 3 , 5 = 1 + 4 = 2 + 3 5=1+4=2+3 5 = 1 + 4 = 2 + 3 , 6 = 1 + 5 = 2 + 4 6=1+5=2+4 6 = 1 + 5 = 2 + 4 。 现在你的任务是将指定的正整数 n n n 分解成若干个互不相同的自然数的和,且使这些自

    2024年02月05日
    浏览(50)
  • 洛谷 CF1743APassword 题解

    https://www.luogu.com.cn/problem/CF1743A 已知一个长度为四的,只包含字符 0 , 1 , 2 , … , 9 0,1,2,dots ,9 0 , 1 , 2 , … , 9 的字符串中不会出现哪些字符,求可能的字符串的数量。 Monocarp has forgotten the password to his mobile phone. The password consists of $ 4 $ digits from $ 0 $ to $ 9 $ (note that it can start wit

    2023年04月20日
    浏览(45)
  • 洛谷AT4888 题解-伦伦数

    A positive integer XX is said to be a lunlun number if and only if the following condition is satisfied: In the base ten representation of XX (without leading zeros), for every pair of two adjacent digits, the absolute difference of those digits is at most 11 . For example, 12341234 , 11 , and 334334 are lunlun numbers, while none of 3141531415 

    2024年02月06日
    浏览(48)
  • 洛谷 U123017 机器人题解

    机器人会按照输入的指令进行移动,命令包括’E’,‘S’,‘W’,\\\'N’四种,分别对应东南西北。执行某个命令时它会消耗1秒钟向对应的方向移动一格单位。 在0时刻机器人位于(0,0)。 如果遇到’E’命令,向右一个单位,即到达(1,0)。如果遇到’S’命令,向下一个单位,即到达

    2024年03月21日
    浏览(41)
  • 洛谷 P1336 最佳课题选择 题解

    题目链接 状态:考虑 (f_{i,j}) 表示前 (i) 种论文里面,一共写了 (j) 篇,的最少花费时间。 转移策略:我们一次考虑每一种论文写多少篇。假设写 (k) 篇, (k in [0,j] cap mathbb{Z}) ,有转移方程: [f_{i,j} = min(f_{i-1,j-k} + text{cost}(i,k)), k in [0,j] cap mathbb{Z}] 其中 [text{

    2024年02月14日
    浏览(36)
  • 洛谷 P3304 [SDOI2013] 直径 题解

    题目链接 第一部分好说,求直径,dfs或者DP都可以。 第二部分,有一个定理,就是所有直径中点重叠。 那么有两种情况 一种是中点在一个节点上,那么显然这个点是每条直径的终点,也就是说直径的一半相等。从这个点出发dfs,找出所有最远点。如果只有两条,输出depth之

    2024年02月14日
    浏览(37)
  • 【洛谷题解】B2010 带余除法

    题目链接:带余除法 - 洛谷 题目难度:入门 涉及知识点:除法,计算余数 题意: 分析:计算商后再用a/商*b得余数 AC代码: 总结:计算商后再用a/商*b得余数

    2024年02月19日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包