CF1324F Maximum White Subtree 题解
简要题意:
给定一棵树,每个点有黑白两种颜色;对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小。输出这些值。
F题也这么简单,咳咳,要是我也熬夜打上那么一场。。。可惜没时间打啊
美国佬怎么想的,不能让比赛设置成美国的上午,那我们就是下午了;非要设置成下午,那我们就是半夜。。。
首先,这题一看就是 \(\texttt{dp}\),树形 \(\texttt{dp}\),换根 \(\texttt{dp}\).
下文中,用 \(\texttt{Subtree(i)}\) 表示 \(i\) 的子树包含的所有节点集合。
用 \(\texttt{father(i)}\) 表示 \(i\) 节点的父亲。
用 \(\texttt{colour_i}\) 表示 \(i\) 节点的颜色值,黑为 \(-1\),白为 \(1\).
首先,假定 \(1\) 为根。
用 \(f_i\) 表示,当前联通图包含在以 \(i\) 为根的子树内的答案。
则必然存在:
\]
因为, \(colour_i\) 是必须包含的,其次是所有子树中的答案统计;负数不统计。
下面考虑一个换根(树形) \(\texttt{dp}\).用 \(g_i\) 表示 整棵树去掉以 \(i\) 为根的子树后(保留 \(i\) 节点)的答案。
\]
这也是显然的。
你发现这玩意儿似乎是 \(O(n^2)\) 的???
可以,你机智地发现,后面和 \(f_i\) 的状态转移方程长得不是一点点像!
接着,我们来看后面的部分。
\]
把这个代入 \(g\) 可知:
\]
然后考虑统计答案。
你可能觉得是这样子的:
\]
可是你机智的发现,连样例都过不了!!!
什么鬼?
\(f_i\) 和 \(g_i\) 都没毛病?
\(ans_i\) 似乎 也没什么问题?
你再次环顾了以下 \(f\) 和 \(g\) 的方程。
你机智的发现,两个函数都计算了 \(colour_i\).
所以还要减掉一个!
\]
天哪,你告诉我这个树形 dp 不会写???
要是 \(1\) 年前的我,这里肯定是记忆化搜索。
但是,我们就用树形 \(\texttt{dp}\) 写,怎么地!
具体见代码。
时间复杂度:\(O(n)\).
空间复杂度:\(O(n)\).
实际得分:\(100pts\).
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1;
inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
int n,a[N],fa[N],f[N];
int g[N],ans[N];
vector<int>G[N];
//正常套路,化树为图,随意求根,形成父亲
inline void solve(int dep,int bs) { //bs 是 dep 的父亲,既方便处理父亲,也为后面的 g 做铺垫
fa[dep]=bs; f[dep]=a[dep]?1:-1;
for(int i=0;i<G[dep].size();i++)
if(G[dep][i]!=bs) {
solve(G[dep][i],dep);
if(f[G[dep][i]]>0) f[dep]+=f[G[dep][i]];
} //加上每个儿子维护的子树值即可,巧妙维护
}
inline void dfs(int dep) {
int x=fa[dep],t=g[x]+f[x]-(a[x]?1:-1);
if(f[dep]>0) t-=f[dep];
if(t<0) t=0; ans[dep]=f[dep]+t;
g[dep]=t+(a[dep]?1:-1);
for(int i=0;i<G[dep].size();i++)
if(G[dep][i]-fa[dep]) dfs(G[dep][i]);
} //维护 g
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<n;i++) {
int x=read(),y=read();
G[x].push_back(y);
G[y].push_back(x);
}
solve(1,0); g[1]=a[1]?1:-1; ans[1]=f[1];
for(int i=0;i<G[1].size();i++) dfs(G[1][i]);
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}
CF1324F Maximum White Subtree 题解的更多相关文章
- CF1324F Maximum White Subtree——换根dp
换根dp,一般用来解决在无根树上,需要以每个节点为根跑一边dfs的dp问题 我们做两遍dfs 先钦定任意一个点为根 第一遍,算出\(f_i\)表示\(i\)的子树产生的答案,这里,子树指的是以我们钦定 ...
- CF1324 --- Maximum White Subtree
CF1324 --- Maximum White Subtree 题干 You are given a tree consisting of \(n\) vertices. A tree is a c ...
- Codeforces 1324F Maximum White Subtree DFS
题意 给你无根一颗树,每个节点是黑色或白色.对于每一个节点,问包含该节点的权值最大的子树. 子树的权值等于子树中白点的个数减去黑点的个数. 注意,这里的子树指的是树的联通子图. 解题思路 这场就这题卡 ...
- Codeforces Round #627 (Div. 3) F - Maximum White Subtree(深度优先搜索)
题意: n 个点 n - 1 条边的树,问每个点所在所有子树中白黑点数目的最大差. 思路: 白点先由下至上汇集,后由上至下分并. #include <bits/stdc++.h> usin ...
- [Leetcode] 1120. Maximum Average Subtree
Given the root of a binary tree, find the maximum average value of any subtree of that tree. (A subt ...
- 【LeetCode】1120. Maximum Average Subtree 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...
- Lintcode400 Maximum Gap solution 题解
[题目描述] Given an unsorted array, find the maximum difference between the successive elements in its s ...
- Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree 题解(贪心+易错)
题目链接 题目大意 给你一课树,要你给每一条边分权值,每条边的权值大于0,他们的乘积等于k,而且要使得n-1条边1的数量尽可能少,定义 f(u,v)为u到v的边权和求 \(\max \sum_{i=1 ...
- CF1092 --- Tree with Maximum Cost
CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...
随机推荐
- 学习HEXO的历程
前言: 简介 开始搭建 命令 API测试 逛github相关的帖子时,发现了hexo.正好想要做一个个人的博客,用来记录自己的各类感悟,所以花一些时间学习学习,以后博客可以放github,省得去注册c ...
- Microsoft Translator:打破语言障碍 拓展全球沟通新机遇
Translator:打破语言障碍 拓展全球沟通新机遇"> 作者:Olivier Fontana, 微软研究院Microsoft Translator产品战略总监 世界越来越小,全球协 ...
- 8.【Spring Cloud Alibaba】配置管理-Nacos
使用Nacos管理配置 架构图 配置文件遵循的格式 bootstrap.yml pom.xml <dependency> <groupId>org.springframewor ...
- Appium自动化测试实践
安装配置Appium环境 安装appium 安装appium有两种方式,一种是通过命令行终端方式,一种是Appium Desktop.这里推荐使用Appium Desktop方式,只需下载下来安装就可 ...
- zookeeper和dubbo安装与搭建(2)
Zookeeper+Dubbo安装与搭建(2) (原创:黑小子-余) 一.环境配置:zookeeper3.6.0 + dubbo3.5.4 + maven3.6.1 + jdk1.8 + tomcat ...
- Python - 超好用的第三方库pathlib,快速获取项目中各种路径
前言 之前曾介绍过Python的os库详细使用方式,具体可看看这篇博文:https://www.cnblogs.com/poloyy/p/12341231.html 博主在学完os库之后,就开始投入使 ...
- ASP.NETMVC中js非空验证实例
页面代码 @using (Html.BeginForm("Edit", "Home", FormMethod.Post, new { @Id = "f ...
- 用Navicat Premium 连接mysql数据库时报错 -- 1130 Host xxxx is not allowed to connect to this MySQL server
用Navicat Premium 连接mysql数据库时报错 报错原因:此时的MySQL默认不能远程连接. 解决方案:修改MySQL配置 具体步骤: 1.登陆服务器,进入数据库 mysql -uroo ...
- sql 语句系列(多表之链)[八百章之第三章]
新增连接查询而不影响其他连接查询 请看图: 这种情况我们一般会使用左连接的方式. select e.ENAME,d.LOC,eb.RECEIVED from emp e join dept d on( ...
- 2018 巅峰极客CTF misc writeup
flows 拿到一个pcap包,用wireshark打开,发现是USB协议,尝试在kali下使用tshark提取,提取失败,发现异常.回到wireshark分析数据.在其中一个数据包中发现了tip 把 ...