携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
[APIO2014] 连珠线
题目描述
在达芬奇时代,有一个流行的儿童游戏称为连珠线。当然,这个游戏是关于珠子和线的。线是红色或蓝色的,珠子被编号为 到 。这个游戏从一个珠子开始,每次会用如下方式添加一个新的珠子:
Append(w, v):一个新的珠子 和一个已经添加的珠子 用红线连接起来。
Insert(w, u, v):一个新的珠子 插入到用红线连起来的两个珠子 之间。具体过程是删去 之间红线,分别用蓝线连接 和 。
每条线都有一个长度。游戏结束后,你的最终得分为蓝线长度之和。
给你连珠线游戏结束后的游戏局面,只告诉了你珠子和链的连接方式以及每条线的长度,没有告诉你每条线分别是什么颜色。
你需要写一个程序来找出最大可能得分。即,在所有以给出的最终局面结束的连珠线游戏中找出那个得分最大的,然后输出最大可能得分。
输入格式
第一行一个正整数 ,表示珠子的数量。珠子从 到 编号。
接下来 行每行三个整数 。保证 。。表示 号珠子和 号珠子间连了长度为 的线。
输出格式
输出一个整数,表示最大可能得分。
样例 #1
样例输入 #1
5
1 2 10
1 3 40
1 4 15
1 5 20
样例输出 #1
60
样例 #2
样例输入 #2
10
4 10 2
1 2 21
1 3 13
6 7 1
7 9 5
2 4 3
2 5 8
1 6 55
6 8 34
样例输出 #2
140
提示
【样例描述1】
可以通过如下方式获得 分:首先从 号珠子开始。
把 和 连起来。(线长度任意)
在 和 之间插入 。(线长分别为 和 )。
把 和 用长度为 的线连起来。
把 和 用长度为 的线连起来。
【限制与约定】
第一个子任务共 13 分,满足 。
第二个子任务共 15 分,满足 。
第三个子任务共 29 分,满足 。
第四个子任务共 43 分,满足 。
#include<cstdio>
#include<climits>
typedef long long ll;
int cnt=0;
ll mx1[200005],mx2[200005],vg[200005];
ll f[200005][2],g[200005][2],k[200005][2];
int son1[200005],son2[200005];
int h[200005],to[400005],ver[400005],w[400005];
inline int read() {
register int x=0,f=1;register char s=getchar();
while(s>'9'||s<'0') {if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') {x=x*10+s-'0';s=getchar();}
return x*f;
}
inline void add(int x,int y,int z) {
to[++cnt]=y;
ver[cnt]=h[x];
w[cnt]=z;
h[x]=cnt;
}
inline void swap(int &x,int &y) {int tmp=x;x=y;y=tmp;}
inline void swap(ll &x,ll &y) {ll tmp=x;x=y;y=tmp;}
inline ll max(const ll &x,const ll &y) {return x>y? x:y;}
inline void dfs1(int x,int fa) {
mx1[x]=mx2[x]=INT_MIN; son1[x]=son2[x]=0;
for(register int i=h[x];i;i=ver[i]) {
int y=to[i];
if(y==fa) continue;
vg[y]=w[i];dfs1(y,x);
f[x][0]+=max(f[y][0],f[y][1]+w[i]);
ll val=f[y][0]+w[i]-max(f[y][0],f[y][1]+w[i]);
if(mx1[x]<val) {son2[x]=son1[x];mx2[x]=mx1[x];son1[x]=y;mx1[x]=val;}
else if(mx2[x]<val) {son2[x]=y;mx2[x]=val;}
}
f[x][1]=f[x][0]+mx1[x];
}
inline void dfs2(int x,int fa) {
for(register int i=h[x];i;i=ver[i]) {
int y=to[i];
if(y==fa) continue;
if(son1[x]==y) {swap(mx1[x],mx2[x]);swap(son1[x],son2[x]);}
k[x][0]=g[x][0]-max(f[y][0],f[y][1]+w[i]);k[x][1]=k[x][0]+mx1[x];
if(fa!=-1) {k[x][1]=max(k[x][1],k[x][0]+k[fa][0]+vg[x]-max(k[fa][0],k[fa][1]+vg[x]));}
g[y][0]=f[y][0]+max(k[x][0],k[x][1]+w[i]);
if(mx1[x]<mx2[x]) {swap(mx1[x],mx2[x]);swap(son1[x],son2[x]);}
dfs2(y,x);
}
}
int main() {
int n=read(); ll ans=0;
for(register int i=1;i<n;++i) {int x=read(),y=read(),z=read(); add(x,y,z);add(y,x,z);}
dfs1(1,-1); g[1][0]=f[1][0]; dfs2(1,-1);
for(register int i=1;i<=n;++i) ans=max(ans,g[i][0]);
printf("%lld",ans);
return 0;
}