算法笔记 - 树的直径

树的直径

定义 性质:

树的直径是树上最长的链,即树上任意两点间距离的最大值,可能有多条。

若树无边权,则所有直径的中点相同。

求法:

两次 DFS

第一次,以任意节点为根,搜索到距离自己最远的点,这个点就是直径的一个端点。

第二次,以第一次求得的点为根,搜索到距离自己最远的点,这个点就是另一个端点。

长度和路径可以在 DFS 中求得。

时间复杂度:Θ(N)

代码:

#include<iostream>
#include<vector>
#include<cstring>
#define int long long
using namespace std;
const int N = 100010;
int n;
vector<int> G[N];
int le, n1, n2, dia[N]; // 直径长度,一个端点,dfs次数,节点
int de[N];
void predfs(int u, int fa)
{
if(de[u] > le)
{
le = de[u]; // 更新长度
n2 = u; // 更新端点
}
for(int i=0; i<G[u].size(); i++)
{
int v = G[u][i];
if(v == fa)
continue;
de[v] = de[u] + 1;
if(n1)
dia[v] = u; // 存储路径
predfs(v, u);
}
}
signed main()
{
cin >> n;
for(int i=1; i<n; i++)
{
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
predfs(1, 0);
memset(de, 0, sizeof(de));
le = 0, n1 = n2;
de[n2] = 1;
predfs(n2, 0);
cout << n1 << ' ' << n2 << ' ' << le << '\n';
// 端点和长度
int t = n2;
for(int i=1; i<=le; i++)
{
cout << t << ' ';
t = dia[t];
} // 路径
return 0;
}
posted @   gctiruct  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示