和上一题的换根树形dp类似,这道就是加上了边权,仍是两次dfs即可
但是这个题的输出会很大,ans初值要赋的大一点(要不然最后两个点会wa)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
long long n,cnt,head[maxn];
long long c[maxn],tot,dis[maxn],f[maxn],size[maxn],ans=1000000000000000;
struct edge
{
int to,nxt,v;
}G[maxn];
void add(int x,int y,int z)
{
G[++cnt].nxt=head[x]; G[cnt].to=y;
G[cnt].v=z; head[x]=cnt;
}
void dfs(int u ,int fa)
{
size[u]=c[u];
for(int i=head[u];i;i=G[i].nxt)
{
int to=G[i].to;
if(to!=fa)
{
dfs(to,u);
size[u]+=size[to];
dis[u]+=dis[to]+size[to]*G[i].v;
}
}
}
void ddfs(int u,int fa)
{
for(int i=head[u];i;i=G[i].nxt)
{
int to=G[i].to;
if(to!=fa)
{
f[to]=f[u]-size[to]*G[i].v+(tot-size[to])*G[i].v;
ans=min(ans,f[to]);
ddfs(to,u);
}
}
}
signed main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%lld",&n);
long long x,y,z;
for(int i=1;i<=n;i++) scanf("%lld",&c[i]),tot+=c[i];
for(int i=1;i<n;i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs(1,1);
f[1]=dis[1];
ans=min(ans,f[1]);
ddfs(1,1);
printf("%lld\n",ans);
return 0;
}