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

输入

输出

备注

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[][],n,head[],num,ans;
struct node{
int pre,to,v;
}e[];
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][]<dp[v][]+e[i].v){
dp[f][]=dp[f][];
dp[f][]=dp[v][]+e[i].v;
}
else dp[f][]=max(dp[f][],dp[v][]+e[i].v);
}
ans=max(ans,dp[f][]+dp[f][]);
}
int main(){
scanf("%d",&n);
int x,y,z;
for(int i=;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
Insert(x,y,z);
Insert(y,x,z);
}
dfs(,);
printf("%d",ans);
}
05-18 01:39