树的直径
参考:树的直径
树的直径:树上最远两点(叶子结点)的距离
算法:从树上任意点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 }