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 \ ...
随机推荐
- 深入 Create React App 核心概念
本文差点难产而死.因为总结的过程中,多次怀疑本文是对官方文档的直接翻译和简单诺列:同时官方文档很全面,全范围的介绍无疑加深了写作的心智负担.但在最终的梳理中,发现走出了一条与众不同的路,于是坚持分享出 ...
- 别再埋头刷LeetCode之:北美算法面试的题目分类,按类型和规律刷题,事半功倍
算法面试过程中,题目类型多,数量大.大家都不可避免的会在LeetCode上进行训练.但问题是,题目杂,而且已经超过1300道题. 全部刷完且掌握,不是一件容易的事情.那我们应该怎么办呢?找规律,总结才 ...
- vue传值(父子传值,非父子传值)
vue组件传值,分为父子传值和非父子传值,父子传值又分为父传子和子传父. 组件之间的传值,实现了数据的联动,是从操作Dom到操作数据一个跳转性的突破,在学习vue双向绑定原理之后, 这种观念就应该继续 ...
- 最大的 String 字符长度是多少?
String 类可以说是在 Java 中使用最频繁的类了,就算是刚刚接触 Java 的初学者也不会陌生,因为对于 Java 程序来说,main 方法就是使用一个 String 类型数组来作为参数的(S ...
- Java带有运算符的字符串转换为Long型
由于项目需要在配置文件中配置一个刷新时间,但是配置文件中取出来来的数据肯定是字符串,然后要将该带有运算符的字符串转换为Long型.具体代码如下: 配置文件system.properties中: ref ...
- echarts设置柱状图颜色渐变及柱状图粗细大小
series: [ { name: '值', type: 'bar', stack: '总量', //设置柱状图大小 barWidth : 20, //设置柱状图渐变颜色 itemStyle: { n ...
- 中国传统色JSON数据
提取自中国色/colors.json 解析后存入数据库,导出插入语句chinese_colors.sql,提取码:5inu [ { "CMYK": [ 4, 5, 18, 0 ], ...
- spring注入相关注解
本次主要整理四个注解 @ComponentScan.@Scope.@Conditional.@Import 1. @ComponentScan(value = "com.xiaoguo&qu ...
- 区间dp - 送外卖
When we are focusing on solving problems, we usually prefer to stay in front of computers rather tha ...
- 内置3D对象-Unity3D游戏开发培训
内置3D对象-Unity3D游戏开发培训 作者:Jesai 2018-02-12 19:21:58 五大面板: -Hierachy:当前场景中的物体 图 1-1 -Project:项目中的所有资源 图 ...