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个不同的 ...
随机推荐
- 判断字符s是否为正整数和正小数
下面一段代码是判断是否为正整数和正小数的:
- hdu5443 线段树 长春网赛
#include<stdio.h> #include<string.h> #define lson l,m,rt<<1 #define rson m+1,r,rt& ...
- oralce update操作
1.基本语法:update 表名 set 列名=表达式 [列名=表达式. . . ] where 条件 2.使用的注意事项: v UPDATE语法可以用新值更新原有表行中的各列 把zs的性别改为女 ...
- CSS Specificity
CSS的specificity特性或称非凡性,它是一个衡量CSS值优先级的一个标准. 其实就是解决冲突,当同一个元素被CSS选择符选中,按照优先权取舍不同的CSS规则. specificity用一个四 ...
- 【Objective-C】-空指针和野指针
一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...
- MapReduce数据流-Mapper
- Logtail提升采集性能
默认性能限制 为防止滥用消耗过多机器资源,我们对默认安装的Logtail进行了一系列的资源限制.默认安装的Logtail最多日志采集速度为20M/s,20个并发发送. 其他资源限制请参考:启动参数 h ...
- poj 1716 Integer Intervals(差分约束)
1716 -- Integer Intervals 跟之前个人赛的一道二分加差分约束差不多,也是求满足条件的最小值. 题意是,给出若干区间,需要找出最少的元素个数,使得每个区间至少包含两个这里的元素. ...
- 非常优秀的Javascript(AJAX) 开发工具:Aptana
非常优秀的Javascript(AJAX) 开发工具:Aptana 下面我要向你介绍一款非常优秀的Javascript(AJAX) 开发工具:Aptana.应为它实在太棒了,所以我忍不住想向你推荐它. ...
- 随机线性网络编码的C语言实现,实现可靠传输:原理(1)
线性方程组,大家都不陌生吧.来一组 A11 *X1 + A12 *X2 + A13 *X3 + A14 *X4 =Q1 A21 *X1 + A22 *X2 + A23 *X3 + A24 *X4 =Q ...