1. 程式人生 > >Tyvj P1520 樹的直徑

Tyvj P1520 樹的直徑

正整數 一個數 span 100% ace tin 有趣的 ostream nod

P1520 樹的直徑

http://www.tyvj.cn/p/1520

時間: 1000ms / 空間: 131072KiB / Java類名: Main

描述

樹的直徑,即這棵樹中距離最遠的兩個結點的距離。每兩個相鄰的結點的距離為1,即父親結點與兒子結點或兒子結點與父子結點之間的距離為1.有趣的是,從樹的任意一個結點a出發,走到距離最遠的結點b,再從結點b出發,能夠走的最遠距離,就是樹的直徑。樹中相鄰兩個結點的距離為1。你的任務是:給定一棵樹,求這棵樹中距離最遠的兩個結點的距離。

輸入格式

輸入共n行
第一行是一個正整數n,表示這棵樹的結點數
接下來的n-1行,每行三個正整數a,b,w。表示結點a和結點b之間有一條邊,長度為w
數據保證一定是一棵樹,不必判錯。

輸出格式

輸出共一行
第一行僅一個數,表示這棵樹的最遠距離

測試樣例1

輸入

4
1 2 10
1 3 12
1 4 15

輸出

27

備註

10%的數據滿足1<=n<=5
40%的數據滿足1<=n<=100
100%的數據滿足1<=n<=10000 1<=a,b<=n 1<=w<=10000Tgotmacp

隨便找個根. 先從下往上, 求出每個點到子樹中最遠和次遠點的距離.(遞歸過程中)

然後再從上往下, 看從上面接下來的路徑能有多長.(遞歸返回時)

直接把每個點的最長和次長加起來.

#include<iostream>
#include<cstdio>
using namespace std;
int dp[10010][3],n,head[10010],num,ans;
struct node{
    int pre,to,v;
}e[20010];
void Insert(int from,int to,int v){
    e[++num].to=to;
    e[num].pre=head[from];
    e[num].v=v;
    head[from]=num;
}
void dfs(int f,int pre){
    
for(int i=head[f];i;i=e[i].pre){ int v=e[i].to; if(v==pre)continue; dfs(v,f); if(dp[f][1]<dp[v][1]+e[i].v){ dp[f][0]=dp[f][1]; dp[f][1]=dp[v][1]+e[i].v; } else dp[f][0]=max(dp[f][0],dp[v][1]+e[i].v); } ans=max(ans,dp[f][1]+dp[f][0]); } int main(){ scanf("%d",&n); int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); Insert(x,y,z); Insert(y,x,z); } dfs(1,0); printf("%d",ans); }

Tyvj P1520 樹的直徑