算法笔记 - 树的直径

这篇具有很好参考价值的文章主要介绍了算法笔记 - 树的直径。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

树的直径

定义 性质:

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

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

求法:

两次 \(DFS\)

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

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

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

时间复杂度:\(\Theta(N)\)文章来源地址https://www.toymoban.com/news/detail-843841.html

代码:

#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;
}

到了这里,关于算法笔记 - 树的直径的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【图论】树的直径

    树的直径即为一棵树中距离最远的两点之间的路径 先以任意一点为起点跑一遍dfs,记录离起点距离最远的点p(这个点一定是直径的一个端点,感性理解一下不证明了),然后再以最远点再跑一遍dfs,记录此时距离最远的点q,那么pq就是该树的直接 树中有负权边时不可以用这

    2024年01月20日
    浏览(44)
  • 树的直径问题

    树的直径就树中所有最短路经距离的最大值 求取树的直径可以使用两遍dfs或者树形dp获得 思路: 我们首先任取一点走dfs,然后拿深度最深的点a(必为直径的端点)为root再做一遍dfs,此时获得的最深深度就是树的直径(离直径端点最远的点当然是直径的另一端点) 证明: 如

    2023年04月13日
    浏览(38)
  • 关于树的直径的一切

    本文使用 CC BY-NC-SA 4.0 许可 。 本文为笔者在 OI 学习中的复习向学习笔记。 部分内容会比较简略。 如有好的习题会不断补充。 以下部分详细证明可见 OI Wiki 。 树的直径 指树上任意两点间距离的最大值。 先以任意点为根找到最远点 (v) 。 再以 (v) 为根找到最远点 (u) 。

    2024年04月08日
    浏览(44)
  • leetcode543--二叉树的直径

    1. 题意 求二叉树上最远两个节点之间的距离。 2. 题解 2.1 暴力 最长路径的三种情况 通过根节点 在左子树 在右子树 通过根节点的最长路径长度一定是左右子树深度之和。 但是这样求左右子树的深度会不断重复,所以复杂度很高。 2.2 动态规划 我们可以在求深度的时候,更新

    2024年04月26日
    浏览(31)
  • LeetCode: 二叉树的直径(java)

    543题:二叉树的直径 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 输入:root = [1,2,3,4,5] 输出:3 解释:3 ,取路径

    2024年02月06日
    浏览(39)
  • LeetCode 热题 100 JavaScript--543. 二叉树的直径

    给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。

    2024年02月14日
    浏览(37)
  • 【图论C++】树的直径(DFS 与 DP动态规划)

    UpData Log👆 2023.9.27 更新进行中 Statement0🥇 一起进步 Statement1💯 有些描述是个人理解,可能不够标准,但能达其意 21-1-1 定义 树上 最远的两个节点之间 的距离被称为 树的直径 ,连接这两个点的路径 被称为 树的最长链 。 21-1-2 性质 1 、这两个最远点一定是叶子节点 1、这 两

    2024年02月07日
    浏览(40)
  • 【ccf-csp题解】第四次csp认证-第四题-网络延时-树的直径

    本题所求的实际上是树的直径,即树中的任意两个结点之间的最大距离 采用的方法是dfs 从根节点开始遍历,对于每一个被dfs的结点m,返回此结点m到所有叶子结点的距离最大的那个即d1,同时在dfs过程当中记录结点m到所有叶子结点的距离第二大的那个,即d2 那么最终答案就是

    2024年02月09日
    浏览(39)
  • 数据结构--树的性质

    常见考点 1 : 结点数 = 总度数 + 1 color{red}常见考点1:结点数=总度数+1 常见考点 1 : 结点数 = 总度数 + 1 结点的度 ―― 结点有几个孩子(分支) 树的度 ―― 各结点的度的最大值 m叉树 ―― 每个结点最多只能有m个孩子的树 常见考点 2 : 度为 m 的树、 m 叉树的区别 color{red}常见考点

    2024年02月12日
    浏览(32)
  • 最小生成树的性质及证明

    性质一:设边 ( u , v ) (u,v) ( u , v ) 是图 G = ( V , E ) G=(V,E) G = ( V , E ) 中权重最小的边,则 ( u , v ) (u,v) ( u , v ) 属于 G G G 的某棵最小生成树。 证明①:(应用定理 23.1 ) 设 A A A 数某个最小生成树边的子集,且 A A A 不包含 ( u , v ) (u,v) ( u , v ) 。 ( u , v ) (u,v) ( u

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包