2024年CCPC网络赛C题题解 —— 种树(gym105336C)

news2024/11/14 2:34:18

      一道不错的树形dp题,想要提升树形dp的糕手们可以做一下,放上题面:

     题意:给你一个有0有1的数,每次可以把一个大小为3(包含3个结点)的结构中,要求至少包含一个1,然后就能把整个块的结点都变成1,问你最少需要这样几次操作能使所有节点都变成1。

    然后赛时其实我没做出来,树形dp这个做法是想到的,但是被J这个线性基卡住了(本人当时没接触过线性基),然后一些题目没有去写。所以我先来讲讲树形dp的解法:

     我们来观察一下,如果这个结构大小要求的是2,那么其实可以直接设置一个有关父节点和子节点的状态转移的dp(这玩意应该比较好想),这道题目如果是大小为3的话,我们可以这样子设置一个dp的状态转移:考虑树形 DP,对于一个子树而言,最多可能有 4 种情况:贡献 1 个给父亲、不需要父亲贡献、父亲贡 献 1 个给该子树、父亲贡献 2 个给该子树。 那么,设 fu,−1/0/1/2 分别表示子树 u 对应的这些情况。转移时考虑枚举 u 所有儿子 v 的情况,注意一 下 u 自己本身是否已经种上树、以及两个 fv1,1、fv2,1 可以合并(即使用一次操作完成)的情况即可。 实现细节可能较多。然后实现的代码是这样的:

#include<bits/stdc++.h>
#define Alex std::ios::sync_with_stdio(false),std::cin.tie(0),std::cout.tie(0);
#define int long long
#define double long double
const int QAQ = 0;
const int mod = 998244353;
const double pi = std::acos(-1.0);
const double eps = 1e-10;

int n,m,p[500005],f[500005][4],g[2][2],h[2][2];
std::vector<int> G[500005];

inline void dfs(int u,int fa)
{
	for(auto v : G[u])
	{
		if(v == fa) continue;
		dfs(v,u);
	}
	for(int i = 0;i <= 1;i++)
	for(int j = 0;j <= 1;j++) g[i][j] = 2e18;
	g[0][p[u]] = 0;
	for(auto v : G[u])
	{
		if(v == fa) continue;
		for(int i = 0;i <= 1;i++)
		for(int j = 0;j <= 1;j++)
		{
			h[i][j] = g[i][j];
			g[i][j] = g[i][j] + f[v][0];
		}
		for(int i = 0;i <= 1;i++)
		{
			g[0][i] = std::min(g[0][i],h[1][i] + f[v][1] + 1);
			g[1][i] = std::min(g[1][i],h[0][i] + f[v][1]);
		}
		for(int i = 0;i <= 1;i++)
		for(int j = 0;j <= 1;j++)
		    g[i][1] = std::min(g[i][1],h[i][j] + f[v][2]);
	}
	f[u][0] = std::min(g[0][1],g[1][0] + 1);
	f[u][1] = g[0][0];
	f[u][2] = std::min(g[0][0],g[1][1]) + 1;
}

signed main()
{
	Alex;
	int _;
	_ = 1;
	std::cin>>_;
	while(_--)
	{
		std::cin>>n>>m;
		for(int i = 0;i <= n + 5;i++)
		for(int j = 0;j <= 2;j++) f[i][j] = 2e18;
		for(int i = 0;i <= 1;i++)
		for(int j = 0;j <= 1;j++)
		{
			g[i][j] = h[i][j] = 2e18;
		}
		for(int i = 0;i <= n + 5;i++) p[i] = 0;
		for(int i = 1;i <= m;i++)
		{
			int x;
			std::cin>>x;
			p[x] = 1;
		}
		for(int i = 0;i <= n + 5;i++) G[i].clear();
		for(int i = 1;i <= n - 1;i++)
		{
			int u,v;
			std::cin>>u>>v;
			G[u].push_back(v);
			G[v].push_back(u);
		}
		dfs(1,0);
		std::cout<<std::min(f[1][0],f[1][2])<<'\n';
	}
	return QAQ;
}


   
   
   
   





第二种做法是贪心:贪心做法 对于一次操作,最多完成两个未完成的节点。 对于一个大小为 siz 的子树,且只有根节点完成了,那么一共需要  siz / 2 次操作。 对子树根节点是否完成进行分类讨论: • 如果根节点已经完成了,那么这个子树对根节点父亲的贡献就有两种情况:用最少次数做完子树 时,是否存在多余的、且对子树根节点的父亲有贡献的操作。 如果根节点没有完成,则直接将 siz 向上传递。直到遇到一个已经完成的祖先,在那个祖先中对 siz 进行统计即可。 总的时间复杂度为 O(n)。这种做法的代码实现是这样的:

#include<bits/stdc++.h>
#define Alex std::ios::sync_with_stdio(false),std::cin.tie(0),std::cout.tie(0);
#define int long long
#define double long double
const int QAQ = 0;
const int mod = 1e9 + 7;
const double pi = std::acos(-1.0);
const double eps = 1e-10;
int f[2000005];
bool p[2000005];
std::vector<int> G[500005];
int n,m,ans = 0;

inline void Fre() { int liujiahui = 142857; }

inline int dfs(int u,int fa)
{
	int res = 0;
	for(auto v : G[u])
	{
		if(v == fa) continue;
		f[v] = dfs(v,u);
	}
	for(auto v : G[u])
	{
		if(v == fa || p[v] == 0) continue;
		int t = f[v];
		if(p[u] == 0 && t != 0) p[u] = 1; 
	}
	for(auto v : G[u])
	{
		if(v == fa || p[v] == 1) continue;
		int t = f[v];
		res += t;
	}
	if(p[u] == 0)
	{
		res++;
		return res;
	}else 
	{
		ans = ans + (res + 1) / 2;
		return res & 1;
	}
}

signed main()
{
	Alex;
	int _;
	_ = 1;
	std::cin>>_;
	while(_--)
	{
		std::cin>>n>>m;
		for(int i = 0;i <= n + 5;i++) p[i] = 0;
		for(int i = 0;i <= n + 5;i++) f[i] = 0;
		for(int i = 0;i <= n + 5;i++) G[i].clear();
		for(int i = 1;i <= m;i++) 
		{
			int x;
			std::cin>>x;
			p[x] = 1;
		}
		for(int i = 1;i <= n - 1;i++)
		{
			int u,v;
			std::cin>>u>>v;
			G[u].push_back(v);
			G[v].push_back(u);
		}
		ans = 0;
		int res = dfs(1,0);
		if(p[1] == 0) ans = ans + (res + 1) / 2;
		std::cout<<ans<<'\n';
	}
	return QAQ;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何管控即时通讯工具?避免聊天泄密|即时通讯管控五大妙招

在如今的数字化办公环境中&#xff0c;即时通讯工具已经成为了员工之间沟通的必备神器。无论是讨论项目进展&#xff0c;还是快速解决问题&#xff0c;它们都极大地提高了工作效率。但便利的背后&#xff0c;却潜藏着一个巨大的隐患——聊天泄密。要如何在享受高效沟通的同时&a…

SQL server 6.5升级到SQL server 2019

背景&#xff1a; 对日项目&#xff0c;客户的旧系统的数据库用的是SQL server 6.5&#xff0c;操作系统是windows NT。新系统要求升级到SQL server 2019&#xff0c;查了下资料发现旧系统的版本实在是太久远了&#xff0c;90年代的。 数据库部分的升级思路是这样的&#xff…

大学生租房平台:SpringBoot框架的设计与实现

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专业…

前端使用 Konva 实现可视化设计器(22)- 绘制图形(矩形、直线、折线)

本章分享一下如何使用 Konva 绘制基础图形&#xff1a;矩形、直线、折线&#xff0c;希望大家继续关注和支持哈&#xff01; 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c;欢迎来提 Issue 哟~ github源码 gitee源码 示例地址 矩形 先上效…

RAG 聊天机器人:用 Langchain 和 Streamlit开启与 PDF 的智能对话

与大量 PDF 文档的交互如今变得前所未有地便捷与智能。想象一下,您可以轻松与您的笔记、书籍和各种文档进行无缝对话,不再需要繁琐的手动查找和处理。 这篇文章将带您逐步构建一个基于 Multi-RAG 和 Streamlit 的 Web 应用程序,该应用程序通过 AI 驱动的聊天机器人来读取、…

【Linux 报错】SSH服务器拒绝了密码。请再试一次。(xshell)

出现该错误 可能的原因&#xff1a; 你写入的登录密码错误了&#xff0c;错误原因有&#xff1a; 1、本来输入就错误了 2、创建用户时&#xff0c;只创建了用户名&#xff0c;但密码没有重新设置 3、多人使用同一台服务器时&#xff0c;该服务器管理员&#xff08;本体&#x…

MyEclipse2020安装教程(图文)

本章教程主要记录如何在Windows上安装MyEclipse2020.。 一、下载安装包 通过网盘分享的文件&#xff1a;Myeclipse 2020.rar 链接: https://pan.baidu.com/s/1fD2P0S0GU_zJlUHTPeXP-A?pwdv71m 提取码: v71m 二、安装步骤 1、打开解压后的文件夹&#xff0c;鼠标右击【myeclip…

农产品管理与推荐系统Python+Django网页界面+计算机毕设项目+推荐算法

一、介绍 农产品管理与推荐系统。本系统使用Python作为主要开发语言&#xff0c;前端使用HTML&#xff0c;CSS&#xff0c;BootStrap等技术和框架搭建前端界面&#xff0c;后端使用Django框架处理应用请求&#xff0c;使用Ajax等技术实现前后端的数据通信。实现了一个综合性的…

威胁建模攻击树和攻击库

威胁建模攻击树和攻击库 1.攻击树概述2.创建新的攻击树&#x1f332;3.真实攻击树的案例诈骗攻击树思维导图式SSL风险攻击树 4.攻击库概述5.CAPEC攻击模式6.OWASP 1.攻击树概述 攻击树&#xff08;Attack Tree&#xff09;是一种用于分析和描述系统安全的工具&#xff0c;广泛…

独立产品灵感周刊 DecoHack #067 - 摸鱼神器与AI视频创作工具

本周刊记录有趣好玩的独立产品/设计/开发相关内容&#xff0c;每周一发布&#xff0c;往期内容同样精彩&#xff0c;感兴趣的伙伴可以到官网查看更多内容。可以邮件订阅或RSS订阅本周刊。欢迎通过 Twitter 私信推荐或投稿。 本期内容涵盖从摸鱼神器、AI视频生成&#xff0c;到乐…

【Linux 运维知识】Linux 编译后的内核镜像大小

Linux 内核镜像的大小取决于多个因素&#xff0c;包括内核的版本、启用的功能、模块的数量以及特定的编译配置。 以下是常见情况下不同内核镜像的大小范围&#xff1a; 1. 标准内核镜像大小 压缩后的内核镜像 (vmlinuz)&#xff1a; 压缩后的内核镜像文件&#xff0c;通常位于…

【西电电装实习】4. 无人机系统

文章目录 前言一、定义概念 缩写定义分类 二、性质系统结构 开源平台三、使用步骤总结参考文献 前言 西电电装实习 - 无人机系统 一、定义概念 缩写 定义 无人机&#xff08;Unmanned Aerial Vehicle&#xff0c;UAV&#xff09;&#xff0c;是无人驾驶的飞行器。它利用无…

StarRocks 培训课程重磅上线!专家出品,助你升级打怪不走弯路!

今年已过了大半&#xff0c;大家的学习进度条进展如何&#xff1f;如果你对 StarRocks 的基础知识还有疑惑&#xff0c;或在寻找系统性的学习方法&#xff0c;不必灰心&#xff0c;因为 Rocky 要来助你一臂之力啦&#xff01; &#x1f389; StarRocks Education 上线 值此 S…

LLM的指令微调新发现:不掩蔽指令

最近看到了一篇挺有意思的论文&#xff0c;叫《指令掩蔽下的指令调整》&#xff08;Instruction Tuning With Loss Over Instructions&#xff0c;https://arxiv.org/abs/2405.14394) 。 这篇论文里&#xff0c;研究者们对一个在指令微调中大家普遍接受的做法提出了疑问&#…

2024.9.10营养小题【1】

收获&#xff1a; 1、上图中第一个红框中的内容有所收获&#xff0c;首先是malloc这个函数。 2、*returnSizen*2 这条语句我觉得不存在也不影响解这道题吧&#xff0c;它的作用是给returnSize这个指针指向的那块内存赋值&#xff0c;这个值是不是不给也可以.......

启动程序时遇到0xc000007b应用程序无法正常启动问题

启动程序时遇到0xc000007b应用程序无法正常启动问题 参考链接&#xff1a; 1、https://www.bilibili.com/read/cv16283667/ 一、问题描述&#xff1a; 启动程序时遇到0xc000007b应用程序无法正常启动问题&#xff0c;问题截图如下&#xff1a; 二、问题原因&#xff1a;错误…

芯片IC的热特性和热阻

芯片IC的热特性和热阻 1.概述2.热特性基础3.热阻4.常用的热阻值5.有效散热的经验法则5.1选择合适的封装5.2尽可能大面积的PCB覆铜5.3增加铜厚5.4用散热焊盘和过孔将多层PCB连接5.5结构散热5.6散热片的合理使用5.7不要在散热走线上覆阻焊层 IC 封装的热特性对 IC 应用和可靠性是…

LSTM处理时序数据:深入解析与实战

大家好&#xff0c;我是你们的深度学习老群群。今天&#xff0c;我们来聊一聊LSTM&#xff08;长短期记忆网络&#xff09;是如何处理时序数据并得到预测结果的。LSTM作为循环神经网络&#xff08;RNN&#xff09;的一种变体&#xff0c;因其能够有效捕捉长期依赖关系&#xff…

nova Flip的AI技能点拉满,这些趣味且实用的功能你知道几个?

随着科技的蓬勃发展&#xff0c;人工智能已经渗透到我们日常生活的各个领域&#xff0c;“AIGC”“AI大模型”成为时下的热门词汇。手机作为承接AI革新技术的重要载体&#xff0c;不仅能够大大提升用户的工作效率&#xff0c;也带来了自然、流畅的操作交互体验。 nova Flip…

RocketMQ搭建集群监控平台

一、概述 RocketMQ有一个对其扩展的开源项目incubator-rocketmq-externals&#xff0c;这个项目中有一个子模块叫rocketmq-console&#xff0c;这个便是管理控制台项目了&#xff0c;先将incubator-rocketmq-externals拉到本地&#xff0c;因为我们需要自己对rocketmq-console…