[jzoj 5776]【NOIP2008模拟】小x游世界树 (树形dp)
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;
}
[jzoj 5776]【NOIP2008模拟】小x游世界树 (树形dp)的更多相关文章
- JZOJ 5776. 【NOIP2008模拟】小x游世界树
5776. [NOIP2008模拟]小x游世界树 (File IO): input:yggdrasil.in output:yggdrasil.out Time Limits: 1500 ms Me ...
- JZOJ5776. 【NOIP2008模拟】小x游世界树
题目:[NOIP2008模拟]小x游世界树: 题目的附加题解给的很清楚,这里只给一个代码: #include<iostream> #include<cstdio> #inclu ...
- [题解](树形dp/换根)小x游世界树
2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...
- BZOJ4446:[SCOI2015]小凸玩密室(树形DP)
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室. 每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...
- [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)
4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...
- 牛客挑战赛30 小G砍树 树形dp
小G砍树 dfs两次, dp出每个点作为最后一个点的方案数. #include<bits/stdc++.h> #define LL long long #define fi first # ...
- 【BZOJ5072】[Lydsy十月月赛]小A的树 树形DP
[BZOJ5072][Lydsy十月月赛]小A的树 题解:考虑我们从一个联通块中替换掉一个点,导致黑点数量的变化最多为1.所以我们考虑维护对于所有的x,y的最大值和最小值是多少.如果询问的y在最大值和 ...
- BZOJ.4446.[SCOI2015]小凸玩密室(树形DP)
BZOJ LOJ 洛谷 (下面点亮一个灯泡就说成染色了,感觉染色比较顺口... 注意完全二叉树\(\neq\)满二叉树,点亮第一个灯泡\(\neq\)第一次点亮一号灯泡,根节点应该就是\(1\)... ...
- BZOJ5072:[Lydsy1710月赛]小A的树(树形DP)
Description BZOJ只是扔了个下载链接 Solution 设$f[x][i]$表示$x$点选中$i$个黑点的最小连通块. 设$g[x][i]$表示$x$点选中$i$个黑点的最大连通块. 转 ...
随机推荐
- 以"小刀会“的成败论当今创业成败
讲起"小刀会",熟悉的人或许非常熟悉,不熟悉的人或许根本不知道清末有这样一个组织. 依据翻查史料,最初的小刀会是在福建成立的,来源有两个.一个是天地会的分支,一个是白莲教分支. 而 ...
- SpringMVC案例2----基于spring2.5的注解实现
和上一篇一样,首先看一下项目结构和jar包 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVuamFtaW5fd2h4/font/5a6L5L2T/fo ...
- 一个伟大的发现,装X一下。笔记本win7系统64位机器执行unity 时,屏幕模糊解决的方法
笔者笔记本win7系统64位机器执行unity 时.往往切换时unity界面屏幕模糊,后来发现此时须要下载DirectXRuntimes201006x64,安装就可以.
- Coder-Strike 2014
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove? viewmode=contents by---cxlove Qualification Round 略 Ro ...
- oc35--自定义构造方法
// // Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property int ag ...
- oracle buffer cache的基本原理
Buffer cache 的原理 一. 1·)当一个服务器进程需要读数据到buffer cache中时,首先必须判断该数据在buffer 中是否存在,如果存在且可用,则获取该数据,根据lru算法在lr ...
- B2568 比特集合 树状数组
啊啊啊,跳题坑死人.抽了一道国集的题,自己瞎编了一个算法,好像过不了而半途而废.转去看题解,发现用二维树状数组维护一下,偏移量我倒是想对了,但是维护的东西和我的完全不一样.还是有很大差距啊... 题解 ...
- [SpringMVC]定义多个前缀映射的问题
转自:https://penciltim.iteye.com/blog/501073 我在web.xml里面定义多个dispatch-servlet的前缀映射,像下面这样 <!-- Servle ...
- express4里要单独安装cookie-parser和express-session
express4里要单独安装cookie-parser和express-session express4里要单独安装cookie-parser和express-session: 1 2 npm ins ...
- 第2章 安装Nodejs 2-3 Windows下安装Nodejs
http://nodejs.org