题面

可以水水换根的,不过我是另一种做法:(按点权)找重心,事实上这是重心的一个性质

考虑换根的这个过程,当我们把点放在重心时,我们移动这个点有两种情况:

1.移动到最大的那个子树里

可以发现这个最大的子树的$size$不可能超过其余子树的$size$之和(最多是有两个重心的时候等于其他子树的$size$之和),不然你找的是假重心

2.移动到其他的子树里

显然这样只会让答案变差

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
long long dis[N],val[*N],num[N],maxx[N],siz[N];
int p[N],noww[*N],goal[*N],vis[N];
long long ans,tot,t3,maxn=1e16;
int n,c,t1,t2,cnt;
void link(int f,int t,long long v)
{
noww[++cnt]=p[f],p[f]=cnt;
goal[cnt]=t,val[cnt]=v;
}
void MARK(int nde,int fth)
{
siz[nde]=num[nde];
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
MARK(goal[i],nde);
siz[nde]+=siz[goal[i]];
maxx[nde]=max(maxx[nde],siz[goal[i]]);
}
maxx[nde]=max(maxx[nde],tot-siz[nde]);
if(maxx[nde]<maxn) maxn=maxx[nde],c=nde;
}
void DFS(int nde,int fth)
{
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
dis[goal[i]]=dis[nde]+val[i];
DFS(goal[i],nde);
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lld",&num[i]),tot+=num[i];
for(int i=;i<n;i++)
{
scanf("%d%d%lld",&t1,&t2,&t3);
link(t1,t2,t3),link(t2,t1,t3);
}
c=; MARK(,); DFS(c,);
for(int i=;i<=n;i++)
ans+=dis[i]*num[i];
printf("%lld",ans);
return ;
}

最新文章

  1. MyEclipse设置像visual studio一样的智能提示
  2. Android开发自学笔记(Android Studio1.3.1)&mdash;3.Android应用结构解析
  3. AVL树插入操作实现
  4. 使scp不用输入密码
  5. 嵌入式jetty
  6. 监控持有sql和被堵塞的sql
  7. 关于安卓启动eclipse错误:找不到元素‘d:devices&#39;的声明
  8. monoTouch for android visual studio c#开发
  9. &lt;hr/&gt;标签改变颜色注意事项
  10. 为什么32位操作系统最大支持4GB内存
  11. VS2013创建Windows服务 || VS2015+Windows服务简易教程
  12. 通过免费开源ERP构建业界领先的供应链+垂直电商平台成功案例分享
  13. Array的 filter() 和 sort()
  14. Python 的异步 IO:Asyncio 简介
  15. right spindle supply short to gnd
  16. 凡事预则立|项目Beta冲刺准备
  17. HTTP协议格式【转】
  18. python 深浅copy的例子
  19. linode下更换内核(debian,ubuntu,centos)
  20. Hadoop之MapReduce(二)序列化,排序及分区

热门文章

  1. 最新!2016中国城市GDP排名出炉
  2. chown命令详情
  3. Python基础系列讲解—动态类型语言的特点
  4. (转)Django配置数据库读写分离
  5. 部署mysql版本项目问题记录
  6. Task 6.2站立会议一
  7. Android笔记-1
  8. vue 使用出现的问题(持续记录)
  9. 操作系统 cmd mini OS
  10. BeTa阶段Day4