ABC348E Minimize Sum of Distances 题解
ABC348E Minimize Sum of Distances
题目大意#
给定一棵共 个节点的树, 第 个点的权重为 。定义 表示树上所有点到节点 的距离乘上权重,即 。求 。
Solve#
一眼换根。
考虑先以节点 为根,则 ,( 表示 的深度)。然后考虑换根求 。
如图,以 时为例。记 为当以 为根时 的子树内的点的权值和。当根从 转移至 时,对于在 的子树里的节点,他们的深度都减少了 ,那么 就总共减少了 ;对于不在 的子树里的点,他们的深度都增加了 ,共增加 。整理一下并推广至所有 ,有: 。
Code#
#include<bits/stdc++.h>
#pragma GCC optimize(1,2,3,"Ofast","inline")
using namespace std;
#define int long long
inline int read()
{
short f=1;
int x=0;
char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a,b,c[100010],f[100010],ans;
vector<int>e[100010];
void dfs(int u,int fa,int d)
{
f[1]+=d*c[u];
for(auto i:e[u])
if(i!=fa) dfs(i,u,-~d),c[u]+=c[i];
}
void dp(int u,int fa)
{
for(auto i:e[u])
if(i!=fa) f[i]=f[u]-c[i]+c[1]-c[i],dp(i,u);
}
signed main()
{
n=read();
for(int i=1;i<n;i=-~i)
a=read(),b=read(),
e[a].push_back(b),e[b].push_back(a);
for(int i=1;i<=n;i=-~i) c[i]=read();
dfs(1,0,0);ans=f[1];dp(1,0);
for(int i=1;i<=n;i=-~i) ans=min(ans,f[i]);
return printf("%lld",ans),0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探