CSDN同步

原题链接

简要题意:

给定一棵树,每个点有黑白两种颜色;对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小。输出这些值。

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\) 为根的子树内的答案。

则必然存在:

\[f_i = colour_i + \sum_{x \in Subtree(i)} \max(f_x,0)
\]

因为, \(colour_i\) 是必须包含的,其次是所有子树中的答案统计;负数不统计。

下面考虑一个换根(树形) \(\texttt{dp}\).用 \(g_i\) 表示 整棵树去掉以 \(i\) 为根的子树后(保留 \(i\) 节点)的答案。

\[g_i = colour_i + \max(0,g_{\texttt{father(i)}} + \sum_{x \in Subtree(\texttt{father(i)})}^{i \not = x} \max(f_x,0))
\]

这也是显然的。

你发现这玩意儿似乎是 \(O(n^2)\) 的???

可以,你机智地发现,后面和 \(f_i\) 的状态转移方程长得不是一点点像!

接着,我们来看后面的部分。

\[\sum_{x \in Subtree(\texttt{father(i)})}^{i \not = x} \max(f_x,0) = f_{\texttt{father(i)}} - \max(0,f_i) - colour_{\texttt{father(i)}}
\]

把这个代入 \(g\) 可知:

\[g_i = colour_i + \max(0,g_{\texttt{father(i)}} + f_{\texttt{father(i)}} - \max(0,f_i) - colour_{\texttt{father(i)}})
\]

然后考虑统计答案。

你可能觉得是这样子的:

\[ans_i = f_i + \max(0,g_i)
\]

可是你机智的发现,连样例都过不了!!!

什么鬼?

\(f_i\) 和 \(g_i\) 都没毛病?

\(ans_i\) 似乎 也没什么问题?

你再次环顾了以下 \(f\) 和 \(g\) 的方程。

你机智的发现,两个函数都计算了 \(colour_i\).

所以还要减掉一个!

\[ans_i = f_i + \max(0,g_i - 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 题解的更多相关文章

  1. CF1324F Maximum White Subtree——换根dp

    换根dp,一般用来解决在无根树上,需要以每个节点为根跑一边dfs的dp问题 我们做两遍dfs 先钦定任意一个点为根 第一遍,算出\(f_i\)表示\(i\)的子树产生的答案,这里,子树指的是以我们钦定 ...

  2. CF1324 --- Maximum White Subtree

    CF1324 --- Maximum White Subtree 题干 You are given a tree consisting of \(n\) vertices. A tree is a c ...

  3. Codeforces 1324F Maximum White Subtree DFS

    题意 给你无根一颗树,每个节点是黑色或白色.对于每一个节点,问包含该节点的权值最大的子树. 子树的权值等于子树中白点的个数减去黑点的个数. 注意,这里的子树指的是树的联通子图. 解题思路 这场就这题卡 ...

  4. Codeforces Round #627 (Div. 3) F - Maximum White Subtree(深度优先搜索)

    题意: n 个点 n - 1 条边的树,问每个点所在所有子树中白黑点数目的最大差. 思路: 白点先由下至上汇集,后由上至下分并. #include <bits/stdc++.h> usin ...

  5. [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 ...

  6. 【LeetCode】1120. Maximum Average Subtree 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...

  7. Lintcode400 Maximum Gap solution 题解

    [题目描述] Given an unsorted array, find the maximum difference between the successive elements in its s ...

  8. Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree 题解(贪心+易错)

    题目链接 题目大意 给你一课树,要你给每一条边分权值,每条边的权值大于0,他们的乘积等于k,而且要使得n-1条边1的数量尽可能少,定义 f(u,v)为u到v的边权和求 \(\max \sum_{i=1 ...

  9. CF1092 --- Tree with Maximum Cost

    CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...

随机推荐

  1. 容易出错的JavaScript题目集锦

    容易出错的JavaScript题目集锦 1.typeof(null) 会得到什么?object,在JavaScript中null被认为是一个对象. 2.下列代码将输出控制台的是什么?为什么? 1234 ...

  2. 公司更需要会哪种语言的工程师?​IEEE Spectrum榜单发布

    IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这也是他们发布的第四届编程语言 Top 榜. 据介绍,IEEE Spectrum 的排序是来自 10 个重要线上数据源的综合,例如 St ...

  3. .NET平台编程语言的衰败

    .NET平台编程语言的衰败 JVM上的编程语言除了Java,其它还有很多,比如最近谷歌公司力捧JVM平台上的语言Kotlin.大数据用的Scala.构建系统用的Groovy..NET平台上的编程语言曾 ...

  4. p标签内不能嵌套块级标签

    今天突然发现一个问题,那就是p标签内不能嵌套块级标签 例如: <p><p></p></p> 会被浏览器解析成 我又把 div 嵌套在里面,发现还是这样 ...

  5. html建立大众点评页面遇到的问题

    大众点评所用知识 HTML.CSS.bootstrap3 遇到的问题 因图片无法对齐 源码:抛弃div改用img后成功对齐 解决后成功对齐 源码: 导航栏文本无法右对齐. 我想到的方法是: div{ ...

  6. Visual Studio Code打开后是黑色的什么都没显示

    测试系统:win7 x64. 问题:打开Microsoft VS Code后是黑色的界面并且什么都没有显示. 截图:本来想放一张图片的,因为当时忘记截了,所以这里就忽略了. 解决办法: 需要安装以下三 ...

  7. 『配置』服务器搭建 Office Online Server2016 实现文档预览 番外 错误篇

    安装一个或多个角色.角色服务或功能失败.找不到源文件.请再次尝试在新的“添加角色和功能”向导会话中安装角色.角色服务或功能,然后在向导的“确认”页中单击“指定备用源路径”以指定安装所需的源文件的有效位 ...

  8. hadoop的伪分布式系统

    1.下载hadoop 链接:https://pan.baidu.com/s/10HBQd57pA4OYNPXe8Dwx9g 提取码:1wtk 运行hadoop需要Java环境,所以还需要安装jdk 链 ...

  9. C# BASS音频库 + 频谱基本用法

    效果图: 使用了 BASS.dll.  BASS.NET.dll   和  PeakMeterCtrl.dll 前面两个负责播放   最后一个负责绘制频谱,本文重点讲的是频谱部分,播放音频部分注意一点 ...

  10. 第四篇(1):企业常用Linux web环境安装配置(apache、php、mysql)

    上篇我们讲了基本的软件包管理和文件操作什么的,现在也要动手安装点有用的东西了吧! 本篇我会写出一个用yum安装apache.php.mysql的方法,最后再运行phpMyAdmin来管理数据库. 1. ...