CF1324 --- Maximum White Subtree
CF1324 --- Maximum White Subtree
题干
You are given a tree consisting of \(n\) vertices. A tree is a connected undirected graph with \(n−1\) edges. Each vertex \(v\) of this tree has a color assigned to it (\(a_v\)=1 if the vertex \(v\) is white and \(0\) if the vertex \(v\) is black).
You have to solve the following problem for each vertex \(v\): what is the maximum difference between the number of white and the number of black vertices you >can obtain if you choose some subtree of the given tree that contains the vertex \(v\)? The subtree of the tree is the connected subgraph of the given tree. More >formally, if you choose the subtree that contains \(cnt_w\) white vertices and \(cnt_b\) black vertices, you have to maximize \(cnt_w−cnt_b\).\(\mathcal{Input}\)
The first line of the input contains one integer \(n\) (\(2 \leq n \leq 2 * 10^5\)) — the number of vertices in the tree.
The second line of the input contains \(n\) integers \(a_1,a_2,\cdots, a_n (0\leq a_i \leq 1)\), where \(a_i\) is the color of the \(i-th\) vertex.
Each of the next \(n−1\) lines describes an edge of the tree. Edge \(i\) is denoted by two integers \(u_i\) and \(v_i\), the labels of vertices it connects \((1 \leq u_i,v_i \leq n,u_i \not= v_i)\).
It is guaranteed that the given edges form a tree.\(\mathcal{Output}\)
Print \(n\) integers \(res_1, res_2, \cdots, res_n\), where \(res_i\) is the maximum possible difference between the number of white and black vertices in some subtree that contains the vertex \(i\).\(\mathcal{Example}\)
\(Case_1\)
\(Input\)
9
0 1 1 1 0 0 0 0 1
1 2
1 3
3 4
3 5
2 6
4 7
6 8
5 9
\(Output\)
2 2 2 2 2 1 1 0 2\(Case_2\)
\(Input\)
4
0 0 1 0
1 2
1 3
1 4
\(Output\)
0 -1 1 -1\(\mathcal{Note}\)
The first example is shown below:
The black vertices have bold borders.
In the second example, the best subtree for vertices \(2\),\(3\) and \(4\) are vertices \(2\),\(3\) and \(4\) correspondingly. And the best subtree for the vertex \(1\) is the subtree consisting of vertices \(1\) and \(3\).\(\mathcal{Tag}\)
dfs and similar
dp
*1800
思路分析
这题要求的是求出对任何一个vertex \(v\),求出包含这个节点的子树\(cnt_w - cnt_b\)的最大值。
暴力想法
首先思考下暴力写法应该如何写。
所以,对于所有可能的路径的贡献值的累加,且贡献值需大于等于\(0\).不妨设\(dp[v]\)代表该结点的最大值。故
\]
假如用暴力写法,就是对于每个结点\(v\),暴力搜索所有的adjacent结点,利用\(dfs\)暴力搜索。但是结点最大为\(2*10^5\)这个暴力算法显然会超时,考虑如何优化。
算法优化
对于从下往上的贡献,可以利用从下往上的\(dfs\)树形\(dp\)进行获取,剩余的就是刨去以\(v\)为根的子树的贡献值比较难求。在这里我们设\(fa\)为结点\(v\)的父节点。\(f_v\)代表从下往上以\(v\)为根的白点数减去黑点数的最大值.\(dp[v]\)代表最终的最大值。因此根据刨去以\(v\)为根的子树的贡献值这个思想,我们可以发现:
\]
就是刨去以\(v\)为根的子树的贡献值。因此最终我们可以写出状态转移方程:
1f[v] & if \;v = root \\
f[v] + max(0, dp[fa] - max(0, f[v])) & if\; v \not= root\\
\end{array}\right.
\]
因此最后我们的思路为:
- 从下往上树形\(dp\),计算\(f_v\)
- 从上往下换根\(dp\),计算\(dp[v]\)
代码
#include<bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using VVI = vector<VI>;
VI a;
VI dp;
VI ans;
VVI e;
void dfs(int x, int fa = -1){
dp[x] = a[x];
for (int to : e[x]){
if (to == fa) continue;
dfs(to, x);
dp[x] += max(0, dp[to]);
}
}
void rdfs(int x, int fa = -1){
ans[x] = dp[x];
for (int to : e[x]){
if (to == fa) continue;
dp[x] -= max(0, dp[to]);
dp[to] += max(0, dp[x]);
rdfs(to, x);
dp[to] -= max(0, dp[x]) ;
dp[x] += max(0, dp[to]);
}
}
int main(){
int n; cin >> n;
a = dp = ans = VI(n);
e = VVI(n);
for (int i = 0; i < n; ++ i){
cin >> a[i];
if (a[i] == 0) a[i] = -1;
}
for (int i = 0; i < n - 1; ++ i){
int x, y;
cin >> x >> y;
-- x, -- y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs(0);
rdfs(0);
for (int ret : ans) cout << ret << " ";
cout << endl;
return 0;
}
第一次在博客园写题解,加油加油! 每天一个CF题!
CF1324 --- Maximum White Subtree的更多相关文章
- CF1324F Maximum White Subtree 题解
原题链接 简要题意: 给定一棵树,每个点有黑白两种颜色:对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小.输出这些值. F题也这么简单,咳咳,要是我也熬夜打上那么一场...可惜没时间打啊 ...
- CF1324F Maximum White Subtree——换根dp
换根dp,一般用来解决在无根树上,需要以每个节点为根跑一边dfs的dp问题 我们做两遍dfs 先钦定任意一个点为根 第一遍,算出\(f_i\)表示\(i\)的子树产生的答案,这里,子树指的是以我们钦定 ...
- 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 ...
- CF1092 --- Tree with Maximum Cost
CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...
- Codeforces 1238F. The Maximum Subtree
传送门 考虑构造一些区间使得树尽可能的 "大" 发现这棵树最多就是一条链加上链上出去的其他边连接的点 构造的区间大概长这样(图比较丑请谅解..$qwq$,图中每一个 "└ ...
- [CF 1238F] The Maximum Subtree 树DP
题意 给定一颗树,求这个树的最大子树,且这个子树是一个good-tree. good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交. 题解 通过分析可以发现 ...
随机推荐
- CSS超链接样式,去除下划线等
控制超链接样式 链接的四种状态: a:link - 普通的.未被访问的链接 a:visited - 用户已访问的链接 a:hover - 鼠标指针位于链接的上方 a:active - 链接被点击的时刻 ...
- springboot 启动时执行方法
Springboot提供了两种“开机启动”某些方法的方式:ApplicationRunner和CommandLineRunner.下面简单介绍下ApplicationRunner 1.创建个Tests ...
- Pytest系列(11)- 失败重跑插件pytest-rerunfailures详细使用
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 环境前提 以下先决条件才能使用py ...
- 启用SELinux保护
启用SELinux保护 案例1:启用SELinux保护 1.1问题 本例要求为虚拟 ...
- 请设计 一个密码生成器,要求随机生成4组10位密码(C语言)
请设计 一个密码生成器,要求随机生成4组10位密码(密码只能由字母和数字组成),每一组必须包含至少一个大写字母,每组密码不能相同,输出生成的密码. #include<stdio.h> #i ...
- 2020 PHP 初级 / 基础面试题,祝你金三银四跳槽加薪 (适合基础不牢固的 PHPer)
1.PHP 语言的一大优势是跨平台,什么是跨平台? PHP 的运行环境最优搭配为 Apache+MySQL+PHP,此运行环境可以在不同操作系统(例如 windows.Linux 等)上配置,不受操作 ...
- GO中的逃逸分析
1.什么是逃逸分析 以前写c/c++代码时,为了提高效率,常常将pass-by-value(传值)“升级”成pass-by-reference,企图避免构造函数的运行,并且直接返回一个指针. 那么这里 ...
- jpa是什么,和hibernate 有什么关系
JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不 ...
- Weblogic-SSRF 漏洞复现
0x01 环境搭建 我这里使用的是vulhub,它几乎包含了所有的漏洞环境.(建议安装在ubuntu上) 有需要的小伙伴来企鹅群自取. 安装好vulhub之后需要cd 到weblogic ssrf 目 ...
- DVWA渗透笔记
Command Injection Low <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ ...