CodeForce - 1187 E. Tree Painting (换根dp)
You are given a tree (an undirected connected acyclic graph) consisting of nn vertices. You are playing a game on this tree.
Initially all vertices are white. On the first turn of the game you choose one vertex and paint it black. Then on each turn you choose a white vertex adjacent (connected by an edge) to any black vertex and paint it black.
Each time when you choose a vertex (even during the first turn), you gain the number of points equal to the size of the connected component consisting only of white vertices that contains the chosen vertex. The game ends when all vertices are painted black.
Let's see the following example:

Vertices 11 and 44 are painted black already. If you choose the vertex 22, you will gain 44 points for the connected component consisting of vertices 2,3,52,3,5 and 66. If you choose the vertex 99, you will gain 33 points for the connected component consisting of vertices 7,87,8 and 99.
Your task is to maximize the number of points you gain.
The first line contains an integer nn — the number of vertices in the tree (2≤n≤2⋅1052≤n≤2⋅105).
Each of the next n−1n−1 lines describes an edge of the tree. Edge ii is denoted by two integers uiui and vivi, the indices of vertices it connects (1≤ui,vi≤n1≤ui,vi≤n, ui≠viui≠vi).
It is guaranteed that the given edges form a tree.
Print one integer — the maximum number of points you gain if you will play optimally.
9
1 2
2 3
2 5
2 6
1 4
4 9
9 7
9 8
36
5
1 2
1 3
2 4
2 5
14 题意:
要把树上每个节点染成黑色,每次只能选择染与黑色点相邻的点,第一次染色随意。
每次染色,所获贡献是,与当前点联通的白色点的个数,包括自身。 思路:
首先以1号节点为根节点,计算出每一个节点的子树大小(siz[i]) ,然后计算出每一个节点的所有子树siz之和(dp[i])。
假设当前根节点是u,子节点是v,那么u去掉v子树的贡献为 :res = dp[u]-dp[v]-siz[v];
dp[v]就会变成 dp[v]=dp[v]+res+(n-siz[v])
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cout<<#x<<" = "<<x<<endl;
#define debug(a, x) cout<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); int Head[maxn];
struct edge{
int v;
int Next;
}e[maxn];
int cnt=;
void add(int x,int y){
e[cnt].v=y;
e[cnt].Next = Head[x];
Head[x]=cnt++;
}
ll dp[maxn];
ll siz[maxn];
bool vis[maxn]; int n;
void dfs(int u){
vis[u]=true;
for(int k=Head[u];~k;k=e[k].Next){
if(vis[e[k].v]){ continue;}
dfs(e[k].v);
siz[u]+=siz[e[k].v];
dp[u]+=dp[e[k].v];
}
siz[u]++;
dp[u]+=siz[u];
} void dfs1(int u){
vis[u]=true;
for(int k=Head[u];~k;k=e[k].Next){
int v = e[k].v;
if(vis[v]){ continue;}
ll res = dp[u]-dp[v]-siz[v];
dp[v]=dp[v]+res-siz[v]+n;
dfs1(v);
}
} int main() {
// ios::sync_with_stdio(false);
// freopen("in.txt", "r", stdin); memset(Head,-,sizeof(Head)); scanf("%d",&n);
for(int i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
} dfs();
memset(vis,,sizeof(vis));
dfs1(); ll ans=;
for(int i=;i<=n;i++){
// printf("%lld ",siz[i]);
ans = max(ans,dp[i]);
}
// printf("\n");
printf("%lld\n",ans);
return ;
}
CodeForce - 1187 E. Tree Painting (换根dp)的更多相关文章
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
- 2018.10.15 NOIP训练 水流成河(换根dp)
传送门 换根dp入门题. 貌似李煜东的书上讲过? 不记得了. 先推出以1为根时的答案. 然后考虑向儿子转移. 我们记f[p]f[p]f[p]表示原树中以ppp为根的子树的答案. g[p]g[p]g[p ...
- 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市
P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...
- 小奇的仓库:换根dp
一道很好的换根dp题.考场上现场yy十分愉快 给定树,求每个点的到其它所有点的距离异或上m之后的值,n=100000,m<=16 只能线性复杂度求解,m又小得奇怪.或者带一个log像kx一样打一 ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...
- Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)
题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...
- bzoj 3566: [SHOI2014]概率充电器 数学期望+换根dp
题意:给定一颗树,树上每个点通电概率为 $q[i]$%,每条边通电的概率为 $p[i]$%,求期望充入电的点的个数. 期望在任何时候都具有线性性,所以可以分别求每个点通电的概率(这种情况下期望=概率 ...
- codeforces1156D 0-1-Tree 换根dp
题目传送门 题意: 给定一棵n个点的边权为0或1的树,一条合法的路径(x,y)(x≠y)满足,从x走到y,一旦经过边权为1的边,就不能再经过边权为0的边,求有多少边满足条件? 思路: 首先,这道题也可 ...
- [Bzoj3743][Coci2015] Kamp【换根Dp】
Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...
随机推荐
- 通过在__init__.py中定义__all__变量,来简化from*import*的书写
下图是一个带被引入使用的包的结构,包名比较长,给书写from*import*带来很多麻烦 为了解决麻烦,在__init__.py编写了如下内容 from .httputil import HTTPUt ...
- 使用php实现单点登录实例详解
1.首先准备两个虚拟域名 127.0.0.1 www.openpoor.com 127.0.0.1 www.myspace.com 2.在openpoor的根目录下创建以下文件 index.php文件 ...
- MaxCompute 项目子账号做权限管理
场景: 一个企业使用多款阿里云产品,MaxCompute是其中一个产品,用的是同个主账号,主账号不是由使用MaxCompute的大数据同学管理, 大数据同学使用的是子账号.大数据同学日常需要给Max ...
- qt开发ROS gui界面环境配置过程总结
这段时间花了点时间配置了在qtcreator5.9.1上开发ros gui界面的环境,终于可以实现导入工程,插断点调试了.总结起来需要注意以下几点: 1.安装插件ros_qtc_plugin,ROS与 ...
- jQuery Css类
通过 jQuery,可以很容易地对 CSS 元素进行操作 jQuery 操作 CSS jQuery 拥有若干进行 CSS 操作的方法.我们将学习下面这些: addClass() - 向被选元素添加一个 ...
- Mysql 数据库优化(一)
一 避免网页访问错误 1 数据库连接timeout产生页面5xx错误 2 慢查询造成页面无法加载 3 阻塞造成数据无法提交 二 增加数据库的稳定性 三 优化用户体验 1 流畅的页面访问速度 2 良好 ...
- Python 基础02 基本数据类型
简单的数据类型以及赋值 变量不需要声明 Python的变量不需要声明,你可以直接输入: >>> a = 10 那么你的内存里就有了一个变量a,它的值是10,它的类型是 integer ...
- win10 + 独显 + Anaconda3 + tensorflow_gpu1.13 安装教程(跑bert模型)
这里面有很多坑,最大的坑是发现各方面都装好了结果报错 Loaded runtime CuDNN library: 7.3.1 but source was compiled with: 7.4.1, ...
- kuangbin专题-连通图A - Network of Schools
这道题的意思是就是 问题 1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校 ...
- hdu 1050 Moving Tables (Greedy)
Problem - 1050 过两天要给12的讲贪心,于是就做一下水贪心练习练习. 代码如下: #include <cstdio> #include <iostream> #i ...