Codeforces 1092 F Tree with Maximum Cost (换根 + dfs)
题意:
给你一棵无根树,每个节点有个权值$a_i$,指定一个点u,定义$\displaystyle value = \sum^v a_i*dist(u,v)$,求value的最大值
n,ai<=2e5
思路:
其实就是找一个节点作为根满足上述最大的value
直接枚举是$O(n^2)$的,肯定不行,我们要用到换根法
换根适用于这种无根树找根,两个跟直接产生的结果又有联系,可以相互转换的情况
对于这一题,我们让sum[u] = 以u为根的子树的$\sum a_i$
这样,从父亲节点u向儿子节点v转移的时候,
假设此时的value(整棵树以u为根)为res,我们要将res的值转化为以v为根的value

大前提:此时u是整棵树的根! //没有这个大前提也可以,你要预处理一下每个节点祖先的$\sum a_i$,然后在下面的操作中搞一下,但是我们完全可以通过只改变sum[u],sum[v]的值来决定到底谁才是整棵树的根,因为无论u,v谁是根,其他节点的sum[]都是不变的!嘻嘻
首先$value_v$相比$value_u$,根(v或u)与以v为根的子树中的每一个节点的距离都小了1
在value上表现为 res -= sum[v]
其次在以v为根的子树之外的节点,跟到那些节点的距离都大了1
所以sum[u] -= sum[v], res += sum[u]
此时因为v要成为整个树的根,所以sum[v]+=sum[u]
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e6+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); vector<int>g[maxn];
int a[maxn];
ll res, ans;
ll sum[maxn]; void dfs(int x, int fa, int h){
int sz = g[x].size();
res += 1ll*h*a[x];
sum[x] = a[x];
for(int i = ; i < sz; i++){
if(g[x][i] == fa)continue;
dfs(g[x][i], x, h+);
sum[x] += sum[g[x][i]];
}
return;
} void dfs2(int x, int fa){
ans = max(res, ans);
int sz = g[x].size();
for(int i = ; i < sz; i++){
int y = g[x][i];
if(y == fa) continue; res -= sum[y];
sum[x] -= sum[y];
res += sum[x];
sum[y] += sum[x]; dfs2(y, x); sum[y] -= sum[x];
res -= sum[x];
sum[x] += sum[y];
res += sum[y];
}
return;
} int main(){
int n;
scanf("%d", &n);
mem(sum, );
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
}
for(int i = ; i < n; i++){
int x, y;
scanf("%d %d",&x,&y);
g[x].pb(y);
g[y].pb(x);
}
res = ;
ans = ;
dfs(,-,);
dfs2(,-);
printf("%lld", ans);
return ;
} /* */
明天(今天)还得磨锤子,赶紧睡觉了
Codeforces 1092 F Tree with Maximum Cost (换根 + dfs)的更多相关文章
- Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...
- Codeforces Round #527 (Div. 3) . F Tree with Maximum Cost
题目链接 题意:给你一棵树,让你找一个顶点iii,使得这个点的∑dis(i,j)∗a[j]\sum dis(i,j)*a[j]∑dis(i,j)∗a[j]最大.dis(i,j)dis(i,j)dis( ...
- Codeforces Round #527 F - Tree with Maximum Cost /// 树形DP
题目大意: 给定一棵树 每个点都有点权 每条边的长度都为1 树上一点到另一点的距离为最短路经过的边的长度总和 树上一点到另一点的花费为距离乘另一点的点权 选定一点出发 使得其他点到该点的花费总和是最大 ...
- CF F - Tree with Maximum Cost (树形DP)给出你一颗带点权的树,dist(i, j)的值为节点i到j的距离乘上节点j的权值,让你任意找一个节点v,使得dist(v, i) (1 < i < n)的和最大。输出最大的值。
题目意思: 给出你一颗带点权的树,dist(i, j)的值为节点i到j的距离乘上节点j的权值,让你任意找一个节点v,使得dist(v, i) (1 < i < n)的和最大.输出最大的值. ...
- Codeforces 1092F Tree with Maximum Cost(树形DP)
题目链接:Tree with Maximum Cost 题意:给定一棵树,树上每个顶点都有属性值ai,树的边权为1,求$\sum\limits_{i = 1}^{n} dist(i, v) \cdot ...
- CF1092 --- Tree with Maximum Cost
CF1324 --- Maximum White Subtree 题干 You are given a tree consisting exactly of \(n\) vertices. Tree ...
- E. Tree Painting(树形换根dp)
http://codeforces.com/contest/1187/problem/E 分析:问得分最高,实际上就是问以哪个节点出发得到的分数最多,而呈现成代码形式就变成了换根,max其得分!!!而 ...
- 2018.12.19 codeforces 1092F. Tree with Maximum Cost(换根dp)
传送门 sbsbsb树形dpdpdp题. 题意简述:给出一棵边权为1的树,允许选任意一个点vvv为根,求∑i=1ndist(i,v)∗ai\sum_{i=1}^ndist(i,v)*a_i∑i=1n ...
- codeforces#1187E. Tree Painting(树换根)
题目链接: http://codeforces.com/contest/1187/problem/E 题意: 给出一颗树,找到一个根节点,使所有节点的子节点数之和最大 数据范围: $2 \le n \ ...
随机推荐
- 高斯消去法解线性方程组(MPI)
用一上午的时间,用MPI编写了高斯消去法解线性方程组.这次只是针对单线程负责一个线程方程的求解,对于超大规模的方程组,需要按行分块,后面会在这个基础上进行修改.总结一下这次遇到的问题: (1)MPI_ ...
- pom.xml引入依赖时顺序错误而编译异常
java.lang.NoClassDefFoundError: Lorg/springframework/beans/factory/access/BeanFactoryReference; at j ...
- Huffman树及其编码(STL array实现)
这篇随笔主要是Huffman编码,构建哈夫曼树有各种各样的实现方法,如优先队列,数组构成的树等,但本质都是堆. 这里我用数组来存储数据,以堆的思想来构建一个哈弗曼树,并存入vector中,进而实现哈夫 ...
- java动态代理、Proxy与InvocationHandler
看了好多关于代理的文章,理解和整理一下. 1.代理的基本构成 抽象角色:声明真实对象和代理对象的共同接口,这样可在任何使用真实对象的地方都可以使用代理对象. 代理角色:代理对象内部含有真实对象的引用, ...
- FlashFXP中文破解 指南
flashfxp是一款使用非常广泛,功能非常更强大的FXP/FTP软件.它拥有显示彩色文字.比较CuteFTP的目录.上传和下载文件.共享文件等众多功能,其中深受用户喜爱的便是目录比较功能,它能够有效 ...
- 【转】Zookeeper原理
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...
- InteliJ IDEA 启动应用出现 Error:failed to create a child event loop 解决方案
1.首先检查自己电脑是否能够联网 2.打开电脑防火墙允许 InteliJ IDEA 进行通信如下图所示
- LeetCode10 Hard,带你实现字符串的正则匹配
本文始发于个人公众号:TechFlow 这是LeetCode的第10题,题目关于字符串的正则匹配,我们先来看题目相关信息: Link Regular Expression Matching Diffi ...
- [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解
orz djq_cpp lgm A 题意 给定一个分别含有 \(\frac n2\) 个左括号和右括号的括号序列 每次可以将序列的一个区间翻转 求一个不超过 \(n\) 次的操作方案,使得操作完之后的 ...
- idea怎么关闭项目
原文地址:https://jingyan.baidu.com/article/a3a3f8112169e78da2eb8a8d.html idea关闭项目可以按File-CloseProject按钮实 ...