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 \ ...
随机推荐
- 网络爬虫简单介绍(python)
一.简介 爬虫就是利用代码大量的将网页前端代码下载下来使用的一种程序,一般来说常见的目的为下: 1.商业分析使用:很多大数据公司都会从利用爬虫来进行数据分析与处理,比如说要了解广州当地二手房的均价走势 ...
- docker-none
禁用容器的网络连接 如果要完全禁用容器上的网络堆栈,可以--network none在启动容器时使用该标志.在容器内,仅创建环回设备.以下示例说明了这一点. 创建容器. $ docker run -- ...
- Spring-Boot使用嵌入式容器,那怎么配置自定义Filter呢
Listener.Filter和Servlet是Java Web开发过程中常用的三个组件,其中Filter组件的使用频率最高,经常被用来做简单的权限处理.请求头过滤和防止XSS攻击等.如果我们使用的是 ...
- ArcEngine语法笔记(VB)
1.获取图层字段 Dim pTable As ITable = pLayer Dim pField As IField pField = pTable.Fields.Field(i) Next 2. ...
- ConcurrentHashMap源码解析 JDK8
一.简介 上篇文章详细介绍了HashMap的源码及原理,本文趁热打铁继续分析ConcurrentHashMap的原理. 首先在看本文之前,希望对HashMap有一个详细的了解.不然看直接看Concur ...
- python——pickle模块的详解
pickle模块详解 该pickle模块实现了用于序列化和反序列化Python对象结构的二进制协议. “Pickling”是将Python对象层次结构转换为字节流的过程, “unpickling”是反 ...
- 使用 git 将代码推送到多个仓库
使用 git 将代码推送到多个仓库 起因 起初,在 GitHub 建了一个仓库,200+ 的 commits .后来(终于在眼泪中明白...误
- Mybatis中jdbcType的类型
具体支持的类型参见:org.apache.ibatis.type.JdbcType ARRAY, BIT, TINYINT, SMALLINT, INTEGER, BIGINT, FLOAT, REA ...
- Java入门 - 语言基础 - 19.方法
原文地址:http://www.work100.net/training/java-method.html 更多教程:光束云 - 免费课程 方法 序号 文内章节 视频 1 概述 2 方法的定义 3 方 ...
- java.lang.UnsupportedOperationException: Manual close is not allowed over a Spring managed SqlSession
java.lang.UnsupportedOperationException: Manual close is not allowed over a Spring managed SqlSessio ...