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 similardp*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的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交. 题解 通过分析可以发现 ...
随机推荐
- 微服务架构盛行的时代,你需要了解点 Spring Boot
随着互联网的高速发展,庞大的用户群体和快速的需求变化已经成为了传统架构的痛点. 在这种情况下,如何从系统架构的角度出发,构建出灵活.易扩展的系统来快速响应需求的变化,同时,随着用户量的增加,如何保证系 ...
- 关于 Vue 中 我对中央事线管理器的(enentBus)误解
由于这段时间公司比较闲,就对vue 中的一些模糊的点做了一些加强,突然就想到了常挂在嘴边兄弟组件传值 我理解的兄弟组件的传值是可以跨理由传值的,比如我从http://localhost:8080/lo ...
- 1018 Public Bike Management (30 分)
There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...
- Vulnhub DC-8靶机渗透
信息搜集 nmap -sP 192.168.146.0/24 #主机发现 nmap -A 192.168.146.146 #Enable OS detection, version detection ...
- openlayers-统计图显示(中国区域高亮)
openlayers版本: v3.19.1-dist 统计图效果: 案例下载地址:https://gitee.com/kawhileonardfans/openlayers-examp ...
- Git常用指令整理(Git Cheat Sheet)
[Toc] 1. 创建 复制一个已创建的仓库:git clone ssh://user@domain.com/repo.git 创建一个新的本地仓库:git init 2. 本地修改 显示工作路径下已 ...
- ThinkPHP3.2.3发送微信模板消息
一.开通模板消息功能 所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限:需要选择公众账号服务所处的2个行业,每月可 ...
- Array(数组)对象-->数组遍历
1.数组的遍历: 方法1:使用for循环语句 /*定义数组*/ var arr=[1,2,3,4,5]; /*遍历*/ for (var i = 0;i<arr.length;i++){ con ...
- Docker搭建Nessus pro笔记
0x01 准备Docker环境 拉取镜像: docker pull ubuntu 创建容器: docker run -p 9922:22 -p 8834:8834 --name nessus -it ...
- 常用Linux命令的基本使用
01.常用Linux命令的基本使用 序号 命令 对应英文 作用 01 ls list 查看当前文件夹下的内容 02 pwd print work directory 查看当前所在文件夹 03 cd [ ...
