树的直径

参考:树的直径

树的直径:树上最远两点(叶子结点)的距离

算法:从树上任意点u开始DFS(BFS)遍历图,得到距离u最远的结点v,然后从v点开始DFS遍历图,得到距离v最远的结点w, 则v、w之间的距离就是树的直径,且复杂度为2趟DFS,因此复杂度为 O(n)

重要性质树上任意点能到的最远点,一定是树的直径的某个端点。

模板

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+10;
 5 const int inf = 0x3f3f3f3f;
 6 const int mod = 998244353;
 7 #define rep(i,first,second) for(int i=first;i<=second;i++)
 8 #define dep(i,first,second) for(int i=first;i>=second;i--)
 9 
10 struct edge{ int to,nxt,val;}e[maxn<<1];
11 int head[maxn<<1],maxdis,maxv,tot;
12 int n;
13 
14 void add(int u,int v,int w){
15     e[tot].to = v;
16     e[tot].nxt = head[u];
17     e[tot].val = w;
18     head[u] = tot++;
19 }
20 
21 //u:dfs到的点; f:u点的父节点; dis:u到源点的距离
22 void dfs(int u,int f,int dis){
23     if( maxdis<dis ){
24         maxdis = dis;
25         maxv = u;
26     }
27     for(int i=head[u];~i;i=e[i].nxt){
28         int v=e[i].to, w=e[i].val;
29         if( v==f ) continue;//父节点已经访问过,防止重复遍历
30         dfs(v,u,dis+w);
31     }
32 }
33 
34 int main()
35 {
36     scanf("%d",&n);
37     memset(head,-1,sizeof(head));
38     rep(i,1,n){
39         int u,v,w;
40         scanf("%d%d%d",&u,&v,&w);
41         add(u,v,w);
42         add(v,u,w);
43     }
44     maxv=1;
45     maxdis=0;
46     dfs(1,-1,0);//从结点1开始遍历,找到离1最远的点maxv及对应的最远距离maxdis
47     maxdis=0;
48     dfs(maxv,-1,0);//从结点maxv开始遍历,找到最远点对应的距离maxdis
49     printf("%d\n",maxdis);
50     return 0;
51 }

 

posted @ 2020-04-06 18:23  swsyya  阅读(411)  评论(0编辑  收藏  举报

回到顶部