魏傳之長坂逆襲
時間限制: 1 Sec 內存限制: 128 MB
題目描述
衆所周知,劉備在長坂坡上與他的一衆將領各種開掛,硬生生從曹操手中逃了出去,隨後與孫權一起火燒赤壁、佔有荊益、成就霸業。而曹操則在赤壁一敗後再起不能,終生無力南下。
建安二十五年(220年),曹操已到風燭殘年,但仍難忘當年長坂的失誤,霸業的破滅。他想如果在劉備逃亡的路中事先佈下一些陷阱,便能拖延劉備的逃脫時間了。你作爲曹操身邊的太傅,有幸穿越到了208年的長坂坡,爲大魏帝國貢獻一份力,佈置一些陷阱。但時空守衛者告訴你你不能改變歷史,不能拖增大劉備的最大逃脫時間,但你身爲魏武之仕,忠心報國,希望能添加一些陷阱使得劉備不論怎麼逃跑所用的時間都一樣。
已知共有n個據點,n-1條棧道,保證據點聯通。1號據點爲劉備軍逃跑的起點,當劉備軍跑到某個據點後不能再前進時視爲劉備軍逃跑結束。在任意一個棧道上放置1個陷阱會使通過它的時間+1,且你可以在任意一個棧道上放置任意數量的陷阱。
現在問你在不改變劉備軍當前最大逃跑時間的前提下,需要添加最少陷阱,使得劉備軍的所有逃脫時間都儘量的大。
輸入
第一行一個數n,表示據點個數。
接下來n-1行每行三個數,ai、bi、ti,表示從據點ai通過第i個棧道到bi耗時ti
輸出
僅包含一個數,爲需要添加的最少陷阱數。
樣例輸入
3
1 2 1
1 3 3
樣例輸出
2
提示
【數據規模和約定】
對於 5%的數據,1<=n<=100000,1<=ti<=200000
對於 100%的數據,1<=n<=500000,ti<=1000000
比較每一個分支取子樹中最大的那個
一層層加上來
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll ans;
int Next[1000005],to[1000005],len[1000005];
int n,head[500005],tot,cnt[500005];
void add(int x,int y,int z)
{
Next[tot]=head[x];
to[tot]=y;
len[tot]=z;
head[x]=tot++;
}
ll dfs(int x,int pre)
{
ll ret=0,sum=0;
cnt[x]=0;
for (int i=head[x];i!=-1;i=Next[i])
{
int y=to[i],z=len[i];
if (y==pre) continue;
ll f=dfs(y,x)+z;
cnt[x]++;
ret=max(f,ret);
sum+=f;
}
ans+=ret*cnt[x]-sum;
cnt[x]++;
return ret;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
head[i]=-1;
for (int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
int ret=dfs(1,-1);
cout<<ans<<endl;
return 0;
}