传送门

Description

小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当他想前往阿瓦隆时发现那里只有圣诞节时才能到达,然而现在已经春天了,不甘心的他将自己的目的地改成了世界树,他耗费了大量的时间,终于将自己传送到了世界树下。世界树是一棵非常巨大的树,它有着许许多多的枝条以及节点,每个节点上都有一个平台。好不容易来到传说中的世界树下,小x当然要爬上去看看风景。小x每经过一条边都会耗费体力值。然而世界树之主想给他弄(gáo)些(dǐan)麻(shì)烦(qíng),于是他在每条边上都设了一个魔法阵,当小x踏上那条边时会被传送回根节点,魔法阵只生效一次。这岂不是要累死小x?幸运的是,每个平台上都有无数个加速器,这些加速器可以让小x在当前节点所连的边上耗费的体力值减少,不同平台的加速器性能不一定相同,但同一个平台的加速器性能绝对相同。世界树之主给了小x一次“换根”的机会,他可以将世界树的任何一个节点变为根,但所有的边都不能改变。小x想问你,将根换为哪个节点能使小x爬到世界树上的每个节点耗费的体力值和最少。默认编号为1的点为初始根。

Input

第一行一个数n,表示有n个节点。

第二行n个数ai,表示每个平台上的加速器的性能。

第三至n+1行,每行三个数bi,ci,di分别表示这条无向边的起点,终点与耗费的能量值

Output

第一行一个数,表示要换成的节点,如果有多个点为根时耗费的体力值都最小,则输出编号最小的那个。如果保持为1是最优的,就输出1。

第二行一个数,表示最小耗费的体力值。

Sample Input

4

2 1 3 3

1 2 3

1 3 4

2 4 6

Sample Output

1

9

Data Constraint

对于20%的数据:n<=100

对于40%的数据:n<=1000

对于60%的数据:n<=8000

对于80%的数据:n<=100000

对于100%的数据:0<n<=700000;ai<=1000;1<=bi,ci<=n;di<=1000。

数据保证一个点的加速器性能绝对小于等于它的所有的边所耗费的能量,保证所有节点都可以到达,保证没有数据与样例相同。

Hint

提示:

样例解释:

如果以第一个点为根,则需要耗费0(到1)+1(到2)+2(到3)+6(到4)=9的能量值。

如果以第二个点为根,则需要耗费2(到1)+0(到2)+4(到3)+5(到4)=11的能量值。

如果以第三个点为根,则需要耗费1(到1)+2(到2)+0(到3)+7(到4)=10的能量值。

如果以第四个点为根,则需要耗费5(到1)+3(到2)+7(到3)+0(到4)=15的能量值。

很明显以第一个点为根是最优的。

Solution

考虑先以1为根节点求出答案

然后往子节点转移

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin)),p1==p2?EOF:*p1++)
using namespace std;
typedef long long LL; char buf[1<<20],*p1,*p2;
inline int read() {
int x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
} const int N=700010;
int n,cnt,root;
int da[N],nxt[N<<1],to[N<<1],cost[N<<1],head[N],siz[N];
LL sum,ans;
LL f[N]; void dfs1(int u,int pre) {
siz[u]=1;
E(i,u) {
int v=to[i];if(v==pre) continue;
dfs1(v,u);
siz[u]+=siz[v];
f[1]+=(LL)max((LL)cost[i]-da[u],0ll)*(LL)siz[v];//1
}
} void dfs2(int u,int pre) {
E(i,u) {
int v=to[i];if(v==pre) continue;
f[v]=f[u]-(cost[i]-da[u])*siz[v]+(cost[i]-da[v])*(n-siz[v]);
if(f[v]<=f[root]) root=f[v]<f[root]?v:min(root,v);
dfs2(v,u);
}
} #define add(a,b,c) nxt[++cnt]=head[a],to[cnt]=b,cost[cnt]=c,head[a]=cnt
int main() {
freopen("yggdrasil.in","r",stdin);
freopen("yggdrasil.out","w",stdout);
n=read();
F(i,1,n) da[i]=read();
F(i,1,n-1) {
int u=read(),v=read(),w=read();
add(u,v,w);add(v,u,w);
}
dfs1(1,0);
root=1;
dfs2(1,0);
printf("%d\n%lld",root,f[root]);
return 0;
}

最新文章

  1. 解决报错 ora-00704 ora-00604 ora-00942 启动不了数据库问题
  2. es6还欠完善的地方
  3. OC 中的block存储位置
  4. Yii2 使用八 使用scenarios
  5. 关于DDD的 认识
  6. 九度oj 1530 最长不重复子串
  7. Epoll在LT和ET模式下的读写方式
  8. WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性
  9. 学习笔记:javascript内置对象:字符串对象
  10. 浅谈使用git进行版本控制
  11. redis测试实践
  12. .net core 灵活读取配置文件
  13. 实用小技巧(一):UIScrollView中上下左右滚动方向的判断
  14. 20135337——Linux实践二:模块
  15. [No0000D2]ClearCSharp编程清理脚本批处理bat
  16. 知乎网的CSS命名规律研究
  17. android中使用toolbar
  18. Java读取xml
  19. 2018.07.10NOIP模拟 Knapsack(单调队列优化dp)
  20. MySQL专题 1 分布式部署数据库同步问题 BinLog

热门文章

  1. 代理server的理解(1):Windows环境下的代理server设置
  2. android.os.Process.killProcess(android.os.Process.myPid())与Activity生命周期的影响
  3. React Native - 认识与环境搭建
  4. Android序列化的存储和读取
  5. 快速排序及三向切分快排——java实现
  6. 第7章 Android中访问网络资源
  7. 部署webservice常见问题汇总
  8. Spring MVC中传递json数据时显示415错误解决方法
  9. Redis学习笔记(二):Redis集群
  10. HDU 1054 Hungary