题意:
题目大意
给定一棵包含N个节点的树,对于节点u,v有点权tu,tv ,边长d(u,v)
定义节点间 P值为,P=(tu+tv)*d(u,v)
对于每一个节点u,求出它与其他所有节点的P值之和
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10000;
typedef long long ll;
ll dp1[N],dp2[N],ans[N];
ll size[N],sum[N];
int h[N<<1],e[N<<1],w[N<<1],ne[N<<1],idx,n,a,b;
ll t[N],c,tot;
void add(int a,int b,int c)
{
e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}
void dfs(int u,int fa)
{
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(v==fa) continue;
dfs(v,u);
size[u]+=size[v];
sum[u]+=sum[v];
dp1[u]+=1ll*size[v]*w[i]+dp1[v];
dp2[u]+=1ll*sum[v]*w[i]+dp2[v];
}
size[u]++;
sum[u]+=t[u];
}
void dfs1(int u,int fa)
{
ans[u]=1ll*t[u]*dp1[u]+dp2[u];
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(v==fa) continue;
dp1[v]=dp1[u]+1ll*w[i]*(n-size[v])-1ll*w[i]*size[v];
dp2[v]=dp2[u]+1ll*w[i]*(tot-sum[v])-1ll*w[i]*sum[v];
dfs1(v,u);
}
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&t[i]),tot+=t[i];
for(int i=1;i<=n-1;i++)
{
scanf("%d %d %lld",&a,&b,&c);
add(a,b,c);add(b,a,c);
}
dfs(1,-1);
dfs1(1,-1);
for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
}