浅谈关于树形dp求树的直径问题
在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径。####
求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这里只介绍树形dp
树形dp求树的直径
我们不妨设1号点为根节点,那么这就可以看做一棵有根树。
设D[x]表示从节点x出发,往以x为根的子树走,能够到达的最远距离。设x的子节点分别为\(y_1,y_2,y_3,...,y_t\),\(edge(x,y)\)表示从x到y的边权,则可以得到状态转移方程:
\(D[x]={(D[y_i]+edge(x,y_i))}_{max}\)
接下来,我们考虑对于每个节点x求出经过x的最长链的长度F[x],整棵树的直径就是max{F[x]}(1<=x<=n)。现在我们考虑如何求F[x]。
对于任意两个节点yi和yj,经过节点x的最长链的长度可以通过四个部分来构成:- D[yi]
- D[yj]
- 从x到yi的距离
- 从x到yj的距离
不妨设j<i,则有:
\(F[x]= {(D[y_i]+D[y_j]+edge(x,y_i)+edge(x,y_j))}_{max}\)
对应代码如下:
void dp(int x){
v[x]=1;
for(register int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(v[y])continue;
dp(y);
ans=max(ans,d[x]+d[y]+edge[i]);
d[x]=max(d[x],d[y]+edge[i]);
}
}
代码解释可以看图:

参考资料:李煜东《算法竞赛进阶指南》
浅谈关于树形dp求树的直径问题的更多相关文章
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- 树形dp - 求树的直径
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...
- 树形DP求树的直径
hdu4607 Park Visit Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- 树形DP求树的重心 --SGU 134
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...
- hdu2196 树形dp经典|树的直径
/* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...
- hdoj2196(树形dp,树的直径)
题目链接:https://vjudge.net/problem/HDU-2196 题意:给出一棵树,求每个结点可以到达的最远距离. 思路: 如果求得是树上最长距离,两次bfs就行.但这里求的是所有点的 ...
- codeforce 337D Book of Evil ----树形DP&bfs&树的直径
比较经典的老题 题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d. 这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来 ...
- CS academy Growing Trees【模板】DP求树的直径
[题意概述] 给出一棵树,树上的边有两个值a和b,你可以在[0,limit]范围内选择一个整数delta,树上的边的权值为a+b*delta,现在问当delta为多少的时候树的直径最小.最小直径是多少 ...
随机推荐
- Codeforces 1093E Intersection of Permutations (CDQ分治+树状数组)
题意:给你两个数组a和b,a,b都是一个n的全排列:有两种操作:一种是询问区间在数组a的区间[l1,r1]和数组b的区间[l2,r2]出现了多少相同的数字,另一种是交换数组b中x位置和y位置的数字. ...
- cocos2d-js 骨骼动画 3.10
近期使用了cocos动画中的骨骼动画,这里记录使用的两种方式(3.10版): 一.cocos自带的动画编辑器导出的动画 ccs.armatureDataManager.addArmatureFileI ...
- php的变量引用详解
<?php class SimpleClass { // property declaration public $var = 'a default value'; // method decl ...
- Linux uname命令
一.简介 uname 命令将正在使用的操作系统名写到标准输出中. 二.语法 -a 显示 -m. -n. -r. -s 和 -v 标志指定的所有信息.不能与 -x 或 -SName 标志连用.如果 -x ...
- 没事写写css
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...
- Entity Framework Tutorial Basics(34):Table-Valued Function
Table-Valued Function in Entity Framework 5.0 Entity Framework 5.0 supports Table-valued functions o ...
- Ubuntu 切换到桌面 快捷键设置
设置完以上步骤后,这接windows系统键+d,即可切换到桌面. ps:按Alt+Tab键,可以切换到自己想要的图标进程.
- java全栈day03--循环高级
今日主要内容介绍1.引用类型变量的创建及使用2.流程控制语句之选择语句3.流程控制语句之循环语句4.循环高级01创建引用类型变量公式 * A: 创建引用类型变量公式 * a: 我们要学的Scanner ...
- ubuntu 12.04 (64位)下安装oracle 11g过程及问题总结
最近公司用到oracle,在ubuntu64位安装了一下,碰到了一些问题,在网上搜索到了一些答案,在此作为笔记记录下来. 1.首先下载oracle并解压不再赘述. 2.安装依赖包 sudo apt-g ...
- [译]Javascript中的闭包(closures)
本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...