题目大意:给定一棵 N 个点的树,初始全是白点。要求你做 N 步操作,每一次选定一个与一个黑点相隔一条边的白点,将它染成黑点,然后获得该白点被染色前所在的白色联通块大小的权值。第一次操作可以任意选点,求可获得的最大权值。

题解:对于答案仅由起始点决定的 dp 采用换根法。

发现对于两个相邻的染了黑色的点来说,这两个点染色的先后顺序会对答案产生影响,但是不会对其他点产生影响。同时,可以发现该问题一旦选定了初始点,无论怎样进行染色,答案均相同。因此,考虑采用换根法,需要计算出相邻两个点先后顺序对答案的影响,根据第一个性质,可知仅需要计算第一次两个点对答案的影响即可。画图可知,相邻两点对答案贡献的差值为 \(n-2*sz[v]\)。

代码如下

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn=2e5+10;
typedef long long LL; int n,sz[maxn];
vector<int> G[maxn];
LL f[maxn],ans; void dfs1(int u,int fa){
sz[u]=1;
for(auto v:G[u]){
if(v==fa)continue;
dfs1(v,u);
sz[u]+=sz[v];
}
ans+=sz[u];
}
void dfs2(int u,int fa){
ans=max(ans,f[u]);
for(auto v:G[u]){
if(v==fa)continue;
f[v]=f[u]+n-2*sz[v];
dfs2(v,u);
}
}
void read_and_parse(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
G[x].pb(y),G[y].pb(x);
}
}
void solve(){
dfs1(1,0);
f[1]=ans;
dfs2(1,0);
printf("%lld\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}

最新文章

  1. CDH5.4.5运行多字符分割记录
  2. Andrew Ng机器学习公开课笔记 -- 支持向量机
  3. Oracle实例和Oracle数据库(Oracle体系结构)
  4. 实战RPM包制作
  5. svg text文字居中
  6. java--九九乘法表
  7. 搭建rtmp直播流服务之1:使用nginx搭建rtmp直播流服务器(nginx-rtmp模块的安装以及rtmp直播流配置)
  8. 前端基础之JavaScript
  9. python爬虫动态html selenium.webdriver
  10. 使用 Nexus Repository Manager 搭建私有docker仓库
  11. SQL kaggle learn with as excercise
  12. Spring详解
  13. APP微信支付报错《商户号该产品权限未开通,请前往商户平台&gt;产品中心检查后重试》
  14. Windows 远程栈溢出挖掘与利用
  15. [转]Visual Studio 2010 中安装Qt 5.1
  16. maven聚合工程tomcat插件启动没有 Starting ProtocolHandler [&quot;http-bio-8081&quot;]
  17. 【BZOJ4817】【SDOI2017】树点染色
  18. php的常量
  19. LeetCode 3Sum (Two pointers)
  20. jsonp跨域远离

热门文章

  1. Ubuntu强制修改root密码
  2. 使用CompletableFuture进行异步任务编排
  3. bochs 2.6.8 常用命令集合
  4. 【有奖征集】报表模板库邀您提反馈,轻松赢取P30!
  5. python学习笔记四 (运算符重载和命名空间、类)
  6. 解决远程连不到CentOS7虚拟机或ifconfig中没有ens33
  7. 小记---------sparkRDD的Transformation 和 Action 及案例 原理解释
  8. Vim命令使用
  9. 使用Python基于百度等OCR API的文字识别
  10. 如何决定使用 HashMap 还是 TreeMap? (转)