Codeforces Global Round 26 E. Shuffle 【换根DP】

E. Shuffle

1

题意

给定一颗 n n n 个节点的树 T T T,现在要求恰好执行下面的程序操作一次

  1. T T T 中选择一个点,作为 T 2 T_2 T2 的新根节点
  2. 将这个点从 T T T 中删除,现在 T T T 被分成了一个或一个以上的连通块树
  3. 对每一个连通块重复上述的操作,并将这个新的点连接到上一个步骤添加到 T 2 T_2 T2 的点

即上述操作是一个递归的过程。

现在要回答经过一次上次的程序后,生成的 T 2 T_2 T2 最多有多少个叶节点

思路

首先我们需要指出结论:除去 T 2 T_2 T2 的根节点,我们能拥有的最大叶子数量就是各个连通块的最大独立集,如果根节点度数为一,我们需要特判并给答案额外加一

这是因为:在我们选择第一个点作为 T 2 T_2 T2 的根节点后,剩下的每一对相邻的点都不可能同时成为叶子,因为它们必定存在一个先后顺序,那么先被选择的那个一定会成为后被选择的那个点的祖先。
那么我们可以得出结论(必要条件):最后的叶子集合一定是一个独立集(点集内部没有边)

假设我们已经有了一个独立集作为最终的目标叶子集合,我们如何保证它们一定是 T 2 T_2 T2 的叶子呢?
我们可以每一步都选择不在 M I S MIS MIS (maximum independent set) 中的点,让它们连接到 T 2 T_2 T2 上,那么最后一定会只剩下我们的叶子集合,即我们的 M I S MIS MIS,它们连接到 T 2 T_2 T2 上自然就是叶子了。
那么到了这里,答案很显然就是最大独立集的大小了,最后特判一下根节点的度数

问题是,我们第一步选择的 T 2 T_2 T2 的根节点是不固定的,我们可以考虑在 T T T 上做 d f s dfs dfs 换根 D P DP DP,通过枚举当前点 u u u 作为根节点,并统计答案

除了当前节点 u u u 外,它将 T T T 分割成了若干个连通子树,那么这些子树内的最大独立集我们可以用类似 树形 D P DP DP 模板题 ”没有上司的舞会“ 的处理方式,以 d p [ u ] [ 0 ] dp[u][0] dp[u][0] 表示 u u u 的子树中,不选 u u u 的最多能选择的点, d p [ u ] [ 1 ] dp[u][1] dp[u][1] 表示选了 u u u,按照独立集的定义,如果 u u u 被选了,那么他的邻居都不能被选

问题在于,如何换根,在线统计当前节点 u u u 的祖先节点的信息?

注意到其实 u u u 的祖先节点也可以看成一颗连通树,我们以 s [ 0 ] s[0] s[0] s [ 1 ] s[1] s[1] 分别表示不选 u u u 的祖先和选了 u u u 的祖先的最大独立集大小。

那么从 u u u 转移到它的儿子 v v v 时, s s s 的变化是: s [ 0 ] = max ⁡ { s 0 , s 1 } + ∑ e ≠ v ∧ e ∈ s o n { u } max ⁡ { d p e , 0 , d p e , 1 } s[0] = \max \{ s_0, s_1 \} + \sum_{e \neq v \wedge e \in son \{u \}} \max \{dp_{e, 0}, dp_{e, 1} \} s[0]=max{s0,s1}+e=veson{u}max{dpe,0,dpe,1}
意思就是:转移到 v v v 时,父亲变为了 u u u,那么 u u u 不选的话, u u u其他儿子可以选或不选(取 max ⁡ \max max), u u u 原本的父亲也可以选或不选

同理, s [ 1 ] = 1 + s 0 + ∑ e ≠ v ∧ e ∈ s o n { u } d p e , 0 s[1] = 1 + s_0 + \sum_{e \neq v \wedge e \in son \{u \}} dp_{e, 0} s[1]=1+s0+e=veson{u}dpe,0
表示选了 u u u,并且其他邻居都不能选。

时间复杂度: O ( n ) O(n) O(n)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;const int INF=0x3f3f3f3f;
const long long INFLL=1e18;typedef long long ll;const int N = 200005;std::vector<int> g[N];
int dp[N][2];
int sum_mx[N];
int sum0[N];
int ans;void dfs0(int u, int fa){dp[u][1] = 1;dp[u][0] = 0;sum_mx[u] = sum0[u] = 0;for(auto v : g[u])if(v != fa){dfs0(v, u);sum_mx[u] += std::max(dp[v][0], dp[v][1]);sum0[u] += dp[v][0];dp[u][0] += std::max(dp[v][0], dp[v][1]);dp[u][1] += dp[v][0];}
}void dfs1(int u, int fa, std::array<int, 2> s){ans = std::max(ans, sum_mx[u] + std::max(s[0], s[1]) + (g[u].size() == 1));for(auto v : g[u])if(v != fa){std::array<int, 2> a;a[0] = std::max(s[0], s[1]) + sum_mx[u] - std::max(dp[v][0], dp[v][1]);a[1] = 1 + s[0] + sum0[u] - dp[v][0];dfs1(v, u, a);}
}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int t;std::cin >> t;while(t--){int n;std::cin >> n;fore(i, 1, n){int u, v;std::cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}dfs0(1, 0);ans = 0;dfs1(1, 0, {0, 0});std::cout << ans << endl;fore(i, 1, n + 1) g[i].clear();}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python邮箱发送如何设置?Python发信方法?

Python邮箱发送邮件需要哪些库&#xff1f;怎么使用Python发信&#xff1f; Python的强大之处在于其丰富的库和模块&#xff0c;使得开发者可以轻松地实现各种功能&#xff0c;包括通过电子邮件发送信息。AokSend将介绍如何在Python中设置和发送电子邮件&#xff0c;以及相关的…

将bookmarks文件导入到edge浏览器

前情&#xff1a; 我的旧电脑上的浏览器保留很多书签&#xff0c;准备导入到新电脑上&#xff0c;于是将bookmarks文件拷贝了出来 方法&#xff1a; 网上的解决方案是将bookmarks文件后缀修改为.html&#xff0c;然后通过浏览器导入&#xff0c;但是尝试后并未成功 如图所示…

18. 四数之和 - 力扣

1. 题目 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; 0 …

免费数据库同步软件

在信息化日益发展的今天&#xff0c;数据同步成为了企业和个人用户不可或缺的一部分。数据库同步软件作为数据同步的重要工具&#xff0c;能够帮助我们实现不同数据库系统之间的数据复制和同步&#xff0c;确保数据的一致性和完整性。本文将介绍几款免费数据库同步软件&#xf…

用“引用“作形参,实现两个变量的值互换

解题思路&#xff1a; 以引用作为形参&#xff0c;在虚实结合时建立变量的引用&#xff0c;使形参名作为实参的"引用"&#xff0c;即形参成为实参的引用。 编写程序&#xff1a; 运行结果&#xff1a; 程序分析&#xff1a; 在定义swap函数声明形参时&#…

有一个主域名跟多个二级子域名时该怎么申请SSL证书?

当您拥有主域名以及多个子域名时&#xff0c;选择合适的SSL证书类型对于确保网站的安全性至关重要。以下是三种SSL证书类型的简要介绍&#xff1a; 单域名SSL证书&#xff1a; 功能&#xff1a;只能绑定单个域名&#xff0c;无论是主域名还是子域名。 适用场景&#xff1a;仅…

(3)图像识别yolov5—训练自定义模型

目录 1. 准备数据集 (1) 收集图像: (2) LabelImg标注图像: 2. 模型训练 3. 评估模型 4. 使用模型进行推理 5. 完整文件下载 YOLOv5 是一个用于目标检测的深度学习模型,它非常流行且易于使用。如果你想使用 YOLOv5 训练自定义的模型,以下是一个基本的步骤指南…

狒狒吃香蕉(二分查找)

狒狒吃香蕉&#xff08;二分查找&#xff09; 这个问题可以形式化为一个搜索问题&#xff0c;在可能的速度范围[1, max]内寻找一个合适的速度K&#xff0c;其中max是香蕉堆中最大一堆的香蕉数量。 我们知道&#xff0c;如果狒狒的速度太慢&#xff0c;她将无法在警卫回来之前吃…

[项目推荐]EmoLLM-心理健康大模型

EmoLLM 是一系列能够支持理解用户-支持用户-帮助用户心理健康辅导链路的开源心理健康大模型&#xff0c;由LLM指令微调而来。它旨在全面理解和促进个体、群体乃至整个社会的心理健康状态。 项目介绍 GitHub&#xff1a;https://github.com/SmartFlowAI/EmoLLM 【EmoLLM项目提供…

Linux---sudo命令

文章目录 目录 文章目录 一.sudo命令简介 二.sudo 命令的特点 三.sudo 相关文件 四.sudo 命令授权配置 一.sudo命令简介 sudo 命令全称“SuperUser Do”&#xff0c;是Linux系统中的一个命令能够使普通用户以超级用户身份去执行某些命令。 二.sudo 命令的特点 sudo能够授权…

论文阅读:All-In-One Image Restoration for Unknown Corruption

发表时间&#xff1a;2022 cvpr 论文地址&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Li_All-in-One_Image_Restoration_for_Unknown_Corruption_CVPR_2022_paper.pdf 项目地址&#xff1a;https://github.com/XLearning-SCU/2022-CVPR-AirNet 代码解读…

诊所管理系统免费软件哪个好一点?

不少诊所管理者&#xff0c;想要寻找一款适合自己诊所的免费诊所管理系统。市场上有多个选择&#xff0c;那么&#xff0c;哪个会好一点呢?在选择适合自己诊所的免费诊所管理系统时&#xff0c;考虑系统的易用性、功能全面性、技术支持以及未来可扩展性是非常重要的。下面&…

在AMD GPU上加速大型语言模型的Flash Attention

Accelerating Large Language Models with Flash Attention on AMD GPUs — ROCm Blogs 引言 在这篇博客文章中&#xff0c;我们将指导您如何在AMD GPU上安装Flash Attention&#xff0c;并提供与在PyTorch中标准SDPA比较其性能的基准测试。我们还将测量Hugging Face中多个大型…

win11联想版,如何下载Visual Basic 6.0精简版

一、背景 Visual Basic 6.0精简版、Visual Basic Mini&#xff0c;等 Win11系统&#xff0c;网上找压缩包下载&#xff0c;无法成功。 二、解决 通过下载联想应用商店&#xff0c;在应用商店中下载 步骤一 hi&#xff0c;推荐你使用联想应用商店&#xff0c;商店提供上万款…

积累和消耗,人生本质的两件事

人生的本质其实就两件事&#xff0c;消耗和积累。 纵观你身边所有的人&#xff0c;他们做的所有的事&#xff0c;基本都可以分为两类。 一、积累 二、消耗 比如说感情&#xff0c;在我们每一个人的青春回忆里&#xff0c;都或多或少有一段刻骨铭心的感情&#xff0c;有些人的感…

sklearn深度学习指南:掌握机器学习的利器

sklearn深度学习指南&#xff1a;掌握机器学习的利器&#xff01; 1. 简介1.1 什么是sklearn&#xff1f;1.2 sklearn的优势和应用领域1.3 为什么要学习和使用sklearn&#xff1f; 2. 安装和环境设置2.1 如何安装sklearn&#xff1f;安装Anaconda&#xff08;Windows/macOS/Lin…

6.8日志系统

当做大型项目的时候&#xff0c;出了bug可能需要借助于日志检查&#xff0c;小项目一般是打断点。 服务器是一直在运行的&#xff0c;不能停止&#xff0c;可以借助于日志检查错误。 日志分为两种&#xff1a;业务级别的日志&#xff08;供用户分析业务过程&#xff09;&…

BarTender软件下载附加详细安装教程

BarTender是美国海鸥科技推出的一款优秀的条码打印软件&#xff0c;应用于 WINDOWS95 、 98 、 NT 、 XP 、 2000 、 2003 和 3.1 版本&#xff0c; 产品支持广泛的条形码码制和条形码打印机&#xff0c; 不但支持条形码打印机而且支持激光打印机&#xff0c;还为世界知名品牌条…

C语言 指针——字符数组与字符指针:字符串的表示与存储

目录 字符串常量 字符串变量&#xff1f; 字符数组的定义和初始化 字符指针的定义和初始化 将字符指针指向一个字符串 用字符数组保存一个字符串 将字符指针指向一个字符数组 使用字符指针的基本原则 使用指针的基本原则 字符串常量 字符串变量&#xff1f;  C 语言…

Steam下载游戏很慢?一个设置解决!

博主今天重装系统后&#xff0c;用steam下载发现巨慢 500MB&#xff0c;都要下载半小时。 平时下载软件&#xff0c;一般1分钟就搞定了&#xff0c;于是大致就知道&#xff0c;设置应该出问题了 于是修改了&#xff0c;如下设置之后&#xff0c;速度翻了10倍。 另外&#x…