树的中心
给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。
输入格式
第一行包含整数 n。
接下来 n−1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。
输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。
数据范围
1≤n≤10000,
1≤ai,bi≤n,
−10^5≤ci≤10^5
输入样例:
-
5
-
2 1 1
-
3 2 1
-
4 3 1
-
5 1 1
输出样例:
2
分析:
树的中心:树中找到一个点,该点到树中其他结点的最远距离最近。
为求得当前点到树中其他节点的最远距离,有两种遍历方式:
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int N = 10000+10; 5 int head[N],nexts[N*2],ver[N*2],edge[N*2]; 6 int tot,INF=0x3f3f3f3f; 7 int down1[N],down2[N],up[N],p[N]; 8 void add(int x,int y,int z){ 9 ver[++tot]=y,edge[tot]=z; 10 nexts[tot]=head[x],head[x]=tot; 11 } 12 //子节点更新父节点 13 int dfs_down(int x,int father){ 14 down1[x]=down2[x]=-INF; 15 for(int i=head[x];i;i=nexts[i]){ 16 int y=ver[i],z=edge[i]; 17 if(y==father) continue; 18 int d=dfs_down(y,x)+z; 19 if(d>down1[x]){ 20 down2[x]=down1[x],down1[x]=d; 21 p[x]=y; 22 } 23 else if(d>down2[x]) down2[x]=d; 24 } 25 if(down1[x]==-INF&&down2[x]==-INF) down1[x]=down2[x]=0; 26 return down1[x]; 27 } 28 //父节点更新子节点 29 void dfs_up(int x,int father){ 30 for(int i=head[x];i;i=nexts[i]){ 31 int y=ver[i],z=edge[i]; 32 if(y==father) continue; 33 if(p[x]==y) up[y]=max(up[x],down2[x])+z; 34 else up[y]=max(up[x],down1[x])+z; 35 dfs_up(y,x); 36 } 37 } 38 int main(){ 39 int n; 40 scanf("%d",&n); 41 for(int i=0;i<n;i++){ 42 int x,y,z; 43 scanf("%d%d%d",&x,&y,&z); 44 add(x,y,z); 45 add(y,x,z); 46 } 47 dfs_down(1,0); 48 dfs_up(1,0); 49 int res=INF; 50 for(int i=1;i<=n;i++){ 51 res=min(res,max(down1[i],up[i])); 52 } 53 printf("%d",res); 54 return 0; 55 }