题目链接:http://codeforces.com/problemset/problem/1092/F
题意:给你一棵树,每个点都有权值。计算一下每个点的:所有其他点的权值 乘以到这个点的距离 之和 比如说对于1节点来说,我们要求的就是其他n-1个节点各自的值乘以到这个点的距离,然后求和。然后我们需要求出每个点的这个值,最后求个最大值就可以了。
自己看了题想了思路觉得不靠谱,又搜了题解瞄了一眼发现我的思路正确,于是就自己做。a了。回头看,题解竟然是mmk大佬的。不知道还能不能称作人生第一树,呜呜呜。
思路:首先2e5个点,爆搜肯定炸。所以树形dp。两个dp数组,一个dpans存下每个点的答案,另一个dpsum存下以这个点为根节点的子树所有值之和。因为2e5个点*最大值2e5,int肯定炸,所以开long long。两次深搜,第一次可以得到真正的dpsum和假的dpans(此时的dpans只包含其子树),再第二次搜索从上往下更新每个节点的dpans即可。第二次搜索核心代码如下:
dpans[u]+=(dpans[pre]-(dpans[u]+dpsum[u])+sum-dpsum[u]);
最后再遍历一下所有点,记录一下最大值就好,下面是AC代码。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
#define cl(a,b) memset(a,b,sizeof(a))
#define maxn 200005
using namespace std;
int n,cnt;//点数 边数 总和!!!
ll sum;
ll val[maxn],dpans[maxn],dpsum[maxn];//各点权值,该节点答案,该子树权值之和
int head[maxn];
struct Side{
int v,next;
}side[maxn<<1];
void init(){
cnt=0,sum=0;
for(int i=1;i<=n;i++){
head[i]=-1;
dpans[i]=dpsum[i]=0;
}
}
void add(int u,int v){
cnt++;
side[cnt].v=v;
side[cnt].next=head[u];
head[u]=cnt;
}
void dfs1(int u,int pre){
for(int i=head[u];i!=-1;i=side[i].next){
int v=side[i].v;
if(v==pre) continue;
dfs1(v,u);
dpans[u]+=(dpans[v]+dpsum[v]);
dpsum[u]+=(dpsum[v]);
}
dpsum[u]+=val[u];
return;
}
void dfs2(int u,int pre){
dpans[u]+=(dpans[pre]-(dpans[u]+dpsum[u])+sum-dpsum[u]);
for(int i=head[u];i!=-1;i=side[i].next){
int v=side[i].v;
if(v==pre) continue;
dfs2(v,u);
}
return;
}
int main(){
scanf("%d",&n);
init();
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
sum+=val[i];
}
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,-1);//搜任意一个节点 这里搜n
for(int i=head[1];i!=-1;i=side[i].next){//只搜根节点的子树们就可以了
int v=side[i].v;
dfs2(v,1);
}
ll maxx=0;
for(int i=1;i<=n;i++){
maxx=max(maxx,dpans[i]);
}
if(n==1) printf("0\n");
else printf("%lld\n",maxx);
return 0;
}
下面是题目
You are given a tree consisting exactly of n vertices. Tree is a connected undirected graph with n−1 edges. Each vertex v of this tree has a value av assigned to it.
Let dist(x,y) be the distance between the vertices x and y. The distance between the vertices is the number of edges on the simple path between them.
Let’s define the cost of the tree as the following value: firstly, let’s fix some vertex of the tree. Let it be v. Then the cost of the tree is ∑i=1ndist(i,v)⋅ai.
Your task is to calculate the maximum possible cost of the tree if you can choose v arbitrarily.
Input
The first line contains one integer n, the number of vertices in the tree (1≤n≤2⋅105).
The second line of the input contains n integers a1,a2,…,an (1≤ai≤2⋅105), where ai is the value of the vertex i.
Each of the next n−1 lines describes an edge of the tree. Edge i is denoted by two integers ui and vi, the labels of vertices it connects (1≤ui,vi≤n, ui≠vi).
It is guaranteed that the given edges form a tree.
Output
Print one integer — the maximum possible cost of the tree if you can choose any vertex as v.
Examples
Input
8
9 4 1 7 10 1 6 5
1 2
2 3
1 4
1 5
5 6
5 7
5 8
Output
121
Input
1
1337
Output
0
Note
Picture corresponding to the first example:
You can choose the vertex 3 as a root, then the answer will be 2⋅9+1⋅4+0⋅1+3⋅7+3⋅10+4⋅1+4⋅6+4⋅5=18+4+0+21+30+4+24+20=121.
In the second example tree consists only of one vertex so the answer is always 0.