time limit per test : 2 seconds
memory limit per test : 256 megabytes
You are given a tree consisting exactly of vertices. Tree is a connected undirected graph with edges. Each vertex of this tree has a value assigned to it.
Let be the distance between the vertices and . 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 . Then the cost of the tree is .
Your task is to calculate the maximum possible cost of the tree if you can choose
arbitrarily.
Input
The first line contains one integer n, the number of vertices in the tree .
The second line of the input contains n
integers
, where
is the value of the vertex
.
Each of the next lines describes an edge of the tree. Edge is denoted by two integers ui and vi, the labels of vertices it connects
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
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
as a root, then the answer will be
.
In the second example tree consists only of one vertex so the answer is always .
题意:
给一个
个点的树,每个点有一个点权
,,
表示
到
的简单路径长度,求一点
使得
最大,答案输出最大值。
题解:
考虑已知以一个点为
点的答案,求其移动到一个相邻的点对答案造成的影响。假设当前
点为
点,当前的答案为
,要将
设为与
相邻的
点,则答案变化为
,
是以
为根的子树的所有点点权之和。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
int n,cnt,ne,h[200004],a[200004];
struct edge{
int to,nt;
}e[400004];
ll suma,ans;
bool vis[200004];
ll dis[200004],val[200004];
void add(int u,int v){
e[++ne].to=v;e[ne].nt=h[u];
h[u]=ne;
}
void dfs(int x){
ans+=a[x]*(dis[x]-1);
for(int i=h[x];i;i=e[i].nt){
if(dis[e[i].to])continue;
dis[e[i].to]=dis[x]+1;
dfs(e[i].to);
val[x]+=val[e[i].to];
}
val[x]+=a[x];
}
void calc(int x,ll now){
ans=max(ans,now);
vis[x]=1;
for(int i=h[x];i;i=e[i].nt){
if(vis[e[i].to])continue;
calc(e[i].to,now+suma-(val[e[i].to]<<1));
}
}
int w33ha(){
ne=0;suma=0;
memset(val,0,sizeof(val));
memset(dis,0,sizeof(dis));
memset(h,0,sizeof(h));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
suma+=a[i];
}
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
ans=0;
dis[1]=1;
dfs(1);
calc(1,ans);
printf("%lld\n",ans);
return 0;
}
int LiangJiaJun(){
while(scanf("%d",&n)!=EOF)w33ha();
return 0;
}