【算法分析】
● 什么是树的直径?树上任意两结点之间最长的简单路径即为树的直径。
若无负权边,可以采用两次 DFS 或者树形 DP 的方法在 O(n) 时间求出树的直径;若有负权边,则只能采用树形 DP 求解树的直径。显然,一棵树可以有多条直径,因为树中可能存在最长长度相等的多条简单路径。
● 树形 DP 法原理
以某结点为根的子树所能延伸的最长路径长度 d1 与次长路径长度 d2 的和 d1+d2 的最大值。特别注意,次长路径与最长路径无公共边。
【算法代码】
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
vector<int> e[N];
int dis[N][2]; //dis[.][0]:最长, dis[.][1]:次最长
int ans;
int n;
void dfs(int u,int fa) {
dis[u][0]=dis[u][1]=0;
for(int x:e[u]) {
if(x==fa) continue;
dfs(x,u);
int t=dis[x][0]+1;
if(t>dis[u][0]) {
dis[u][1]=dis[u][0]; //原来最长变为次最长
dis[u][0]=t; //更新最长
} else if(t>dis[u][1]) {
dis[u][1]=t; //更新次长
}
}
ans=max(ans,dis[u][0]+dis[u][1]);
}
int main() {
cin>>n;
for(int i=1; i<n; i++) {
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0);
cout<<ans<<endl;
return 0;
}
/*
in:
5
1 2
1 3
1 4
4 5
out:
3
*/
【参考文献】
https://blog.csdn.net/y6123236/article/details/135112414
https://www.acwing.com/problem/content/description/4151/
https://blog.csdn.net/triangle_617/article/details/136081972
https://www.luogu.com.cn/problem/P3304
https://blog.csdn.net/hnjzsyjyj/article/details/140253125