描述 Description

树的直径,即这棵树中距离最远的两个结点的距离。每两个相邻的结点的距离为1,即父亲结点与儿子结点或儿子结点与父子结点之间的距离为1.有趣的是,从树的任意一个结点a出发,走到距离最远的结点b,再从结点b出发,能够走的最远距离,就是树的直径。树中相邻两个结点的距离为1。你的任务是:给定一棵树,求这棵树中距离最远的两个结点的距离。

输入格式 InputFormat

输入共n行
第一行是一个正整数n,表示这棵树的结点数
接下来的n-1行,每行三个正整数a,b,w。表示结点a和结点b之间有一条边,长度为w
数据保证一定是一棵树,不必判错。

输出格式 OutputFormat

输出共一行
第一行仅一个数,表示这棵树的最远距离

样例输入 SampleInput

4
1 2 10
1 3 12
1 4 15

样例输出 SampleOutput

27

数据范围和注释 Hint

10%的数据满足1<=n<=5
40%的数据满足1<=n<=100
100%的数据满足1<=n<=10000 1<=a,b<=n 1<=w<=10000

题解

此题求树上最长链,即树的直径,有很多方法
可以如题中所说,用两次bfs,求出1的最远点X,再求X的最远点Y,XY即为直径
这个证明比较容易,大致可以分三步
先证明1,X一定和直径有交
再证明X一定是直径的一个端点
那么找X的最远点Y,XY即为直径
或者可以采用dp做法,基于直径为某个点到其不同子树叶子的最长链+次长链
BFS

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #define ll long long
 7 using namespace std;
 8 ll read(){
 9     int x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 int X,n,q[100005],d[100005];
15 vector<int> e[100005],len[100005];
16 char ch[5];
17 void bfs(int x){
18     X=0;
19     int head=0,tail=1;
20     q[0]=x;
21     memset(d,0,sizeof(d));
22     while(head!=tail){
23         int now=q[head];head++;
24         if(d[now]>d[X]) X=now;
25         for(int i=0;i<e[now].size();i++){
26             if(!d[e[now][i]]&&e[now][i]!=x){
27                 d[e[now][i]]=d[now]+len[now][i];
28                 q[tail++]=e[now][i];
29             }
30         }
31     }
32 }
33 int main(){
34     n=read();
35     for(int i=1;i<n;i++){
36         int u=read(),v=read(),w=read();
37         e[u].push_back(v); len[u].push_back(w);
38         e[v].push_back(u); len[v].push_back(w);
39     }
40     bfs(1); bfs(X);
41     printf("%d\n",d[X]);
42     return 0;
43 }

DP

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define maxn 10005
 6 #define inf 0x7fffffff
 7 using namespace std;
 8 int n,cnt,ans;
 9 int f1[maxn],f2[maxn],last[maxn];  //f1求最长链,f2求次长链
10 struct edge{
11     int to,next,v;
12 }e[maxn<<1];
13 void add(int u,int v,int w){
14     e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
15 }
16 void dp(int x,int fa){
17     for(int i=last[x];i;i=e[i].next){
18         int y=e[i].to;
19         if(y==fa) continue;
20         dp(y,x);
21         if(f1[y]+e[i].v>f1[x]){
22             f2[x]=f1[x];
23             f1[x]=f1[y]+e[i].v;
24         }
25         else f2[x]=max(f2[x],f1[y]+e[i].v);
26     }
27     ans=max(f1[x]+f2[x],ans);
28 }
29 int main(){
30     ios::sync_with_stdio(false);
31     cin>>n;
32     for(int i=1;i<n;i++){
33         int u,v,w;
34         cin>>u>>v>>w;
35         add(u,v,w); add(v,u,w);
36     }
37     dp(1,0);
38     cout<<ans<<endl;
39     return 0;
40 }

转载于:https://www.cnblogs.com/Emine/p/7549869.html

【tyvj1520】 树的直径相关推荐

  1. [51nod] 1766树上的最远点对 树的直径 树剖LCA+ST表静态查询

    题意: 给你一棵带权树,q次查询,每次给出两个区间,[l1,r1][l2,r2][l_1,r_1] [l_2,r_2][l1​,r1​][l2​,r2​]从这两个区间中分别选择两个数字,使得这两个点的 ...

  2. 小A与欧拉路(牛客-树的直径)

    题解: 欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次 问你走完这树上所有的点最短路径是什么. 因为树是没有环的,所以你走到叶子结点的时候需要往回走,也就是再走一 ...

  3. luogu P4408 [NOI2003]逃学的小孩(树的直径)

    整理的算法模板合集: ACM模板 看了半天的题原来没有告诉你三个点的坐标,不然直接跑最短路即可.要求最长的时间,所以我们要自己找到三个点,而在树中最长的路径也就是树的直径.那么本题就可以简化为:在一棵 ...

  4. 模板 - 树上问题(树的直径、动态查询树的直径、树的重心)

    整理的算法模板合集: ACM模板 目录 一.树的直径 树形DP 两次DFS / BFS(找到直径的两个端点) 二.动态修改树的边权并求每个时刻的直径(线段树) 三.树的重心 一.树的直径 树的直径满足 ...

  5. 【树的直径】解题报告: luogu P3629 [APIO2010]巡逻(树的直径,位运算成对变换,思维)

    题目链接:P3629 [APIO2010]巡逻 首先看题,从1号结点开始,全部遍历并回到1号结点会恰好经过所有的边两次,这样总长度为 2∗(n−1)2*(n-1)2∗(n−1). 那么如果建立一条路以 ...

  6. 0x63.图论 - 树的直径与最近公共祖先

    目录 一.树的直径(Diameter) 1.树形DP求树的直径 2.两次BFS/DFS求树的直径 1.POJ 1985.Cow Marathon(DFS求树的直径模板题) 2.AcWing 350. ...

  7. [Bzoj2282]消防(二分答案+树的直径)

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  8. 树的直径【p3629】[APIO2010]巡逻

    Description 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一 ...

  9. Codeforces 337D Book of Evil:树的直径【结论】

    题目链接:http://codeforces.com/problemset/problem/337/D 题意: 给你一棵树,n个节点. 如果一个节点处放着"罪恶之书",那么它会影响 ...

最新文章

  1. mysql 2003错误 10055_MYSQL无法连接 提示10055错误的解决方法
  2. OpenCV区域提取之利用Rect提取在源代码中预先定义好的区域
  3. GLSL着色语言学习。橙皮书第一个例子GLSL+OpenTK+F#的实现。
  4. Linux服务器文件描述符最大值修改
  5. 在sql2005中加数据库时出现无法打开物理文件
  6. HTML的a标签置灰不可点击
  7. python少儿编程课件ppt_Python课程第五期
  8. 这是我拼命做科研的原因,2018年最感人的一个真实故事
  9. mysql主从不同步 tar_Mysql主从不同步问题处理案例
  10. 扫地机器人什么牌子好?2021最新扫地机器人排行榜
  11. 【Linux下Inotify + Rsync文件实时同步】
  12. 蓝桥杯 ADV-95 算法提高 字符串比较
  13. 光伏组件市场价格战下谁获益?
  14. Android Wifi 调试
  15. 在linux服务器上安装sublime编辑器
  16. 代码审查工具rietveld的安装与使用(一)
  17. 6个在线正则表达式工具
  18. python计算模型psi_模型稳定度指标PSI与IV
  19. 关于给汶川地震灾区捐款
  20. spring boot注解@PostConstruct

热门文章

  1. Phoronix Test Suite 0.7.0发布Linux下的测试软件
  2. 像msn那样的message提示
  3. centos7下修改/找回mysql的密码,我这里是mysql5.7
  4. 软件质量模型(学习笔记)
  5. ymodem传输的终端工具_Serial for Mac(现代化的终端设计软件)
  6. tidyr | 批量处理数据的前奏——数据嵌套化
  7. linux en_us支持什么格式的中文,更改Linux操作系统下的显示默认支持语言
  8. 新手学vue还是react?
  9. 【顺序表和链表】实现增删查改数据结构 OJ题编程
  10. Oracle count函数原理,oracle count函数