2016暑期集訓10 A魏傳之長坂逆襲

魏傳之長坂逆襲
時間限制: 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章