题目链接


题目大意:

给定一颗树,求这个树的最大子树,且这个子树是一个good-tree。

good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交


解题思路:

  1. 根据线段相交,假设以rootrootroot节点为根,那么我们可以选择两条棵子树进行向下递归继续选择,其他的儿子节点只能选自己,因为线段只有两端向外延伸
  2. 如果不是根节点那么我们只能选一个子树向下延伸,其他都是只能直接选儿子
  3. 那么我们就是要枚举所以点为根去dp,然后更新答案
  4. 但是这样会超时,那么我们就要进行换根dp!
  5. 我们看看要保存什么记录?
  6. 对于每个点我们要记录下面的最大值和次大值的子树,那么我们就选这两个子树进行延伸,其他就直接选。
  7. 换根的时候我们要看看看当前点和根节点之间的关系?
  8. 如果根节点的最大值和次大值里面有一个来着你,那么你就选另一个!
  9. 然后再更新你自己的次大值和最大值就可以了

AC code

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
template<typename T> void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {read(first);read(args...);
}
vector<int> G[maxn];
int dp[maxn], n;
int ans;
pii inf[maxn];
void dfs1(int u, int fa) {inf[u] = {0,0};// inf[u].first 记录最大值,second 记录次大值for(auto it : G[u]) {if(it == fa) continue;dfs1(it,u);if(dp[it] > inf[u].first) inf[u].second = inf[u].first, inf[u].first = dp[it];else if(dp[it] > inf[u].second) inf[u].second = dp[it];}// max 部分算的是不向下延伸的子树的个数 除了根节点都不加次大值dp[u] = max((int)G[u].size()-2,0)+inf[u].first+inf[u].second*(u==1)+1;
}void dfs2(int u, int fa) {if(u != 1) {int maxf = (inf[fa].first == dp[u]) ? inf[fa].second : inf[fa].first;maxf = maxf + max((int)G[fa].size()-2,0)+1; // fa变成子树的贡献// 更新if(maxf > inf[u].first) inf[u].second = inf[u].first, inf[u].first = maxf;else if(maxf > inf[u].second) inf[u].second = maxf;dp[u] = max((int)G[u].size()-2,0)+inf[u].first+inf[u].second+1;}ans = max(ans,dp[u]);for(auto it : G[u]) {if(it == fa) continue;dfs2(it,u);}
}int main() {IOS;int T;cin >> T;while(T --) {cin >> n;for(int i = 1; i <= n; ++ i) G[i].clear();for(int i = 1; i < n; ++ i) {int u, v;cin >> u >> v;G[u].push_back(v);G[v].push_back(u);}dfs1(1,0);dfs2(1,0);cout << ans << endl;ans = 0;}
}

树形dp ---- 树形换根dp F - The Maximum Subtree相关推荐

  1. 树形(dp+换根dp)

    普通树形dp 树形dp通常围绕根节点来写状态转移方程 用一道基础的树形dp例题来具体分析: 没有上司的舞会 Ural 大学有 N 名职员,编号为 1∼N. 他们的关系就像一棵以校长为根的树,父节点就是 ...

  2. 2019长沙学院新生赛(A水,B水,C(整除分块),D水,E(巧数学),F(二分+bfs),H(换根dp),I(线段树)J(dp+倍增+lca))

    A-XOR SUM 通过简单观察得知连续四个数的异或值就是等于0,暴力找出左区间和右区间就可以了,最多跑四个单位 0^1^2^3==0   4^5^6^7=0 #include<bits/std ...

  3. 2020牛客多校第一场B虚树+质数筛+换根dp

    题目大意: 1.可以发现阶乘增长是很快的所以你要把整颗树建立出来是不实际的. 2.我们可以假设这棵树已经建出来出来了我们应该怎么搞 首先很明显是一个树形dp, 我们设dp[j],是以j为u到其他点距离 ...

  4. 小G砍树 (换根dp)

    小G砍树 给你一棵n个节点的带标号无根树.每次,你可以选择一个度数为1的节点并将它从树上移除.问总共有多少种不同的方式能将这棵树删到只剩 1 个点.两种方式不同当且仅当至少有一步被删除的节点不同. 思 ...

  5. Hile每日算法-3.31-树形dp之换根法

    树形dp之换根法 周二周三真的太难了,有早课导致不能熬夜,于是就只能趁着中午的时间写一写,这几天先写点简单的东西,就当重新复习了,应该算是给初学者的知识普及,其他的过了周三再说. 首先来讲一下树的重心 ...

  6. 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)

    题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...

  7. BZOJ 2159 「国家集训队」Crash 的文明世界(第二类斯特林数,换根DP)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2159 是 hydro 的 BZOJ ...

  8. 换根dp求树所有节点的最小深度

    链接:https://ac.nowcoder.com/acm/contest/18072/A 牛妹有一张连通图,由n个点和n-1条边构成,也就是说这是一棵树,牛妹可以任意选择一个点为根,根的深度为0, ...

  9. [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]

    题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...

最新文章

  1. Android调用前置摄像头的方法
  2. IBatis常见错误集锦
  3. 试分析下列程序段:请选择(L1、L2、L3或L4)填入相应的括弧中
  4. 处理自己的数据集_手写代码实现KDD CUP99数据集的数据归一化处理
  5. IDEA编译通过能运行但是出现红色下划线
  6. 循环计数_FOR 循环
  7. 设计糟糕的 RESTful API 就是在浪费时间!
  8. IPS不用添加service帐号进入linux使得管理主机能访问的方法
  9. Linux 命令(113)—— seq 命令
  10. 2015-02-10
  11. 松下新一代电力线通信(PLC)技术经IEEE P1901.3工作小组批准成为基准规范
  12. 2018.11.05._PYTHN_DJANGO_CLASS 144~CLASS147
  13. 80后小学计算机课上的游戏,80后最值得回味的经典课间游戏
  14. AI绘图第二弹!绘制专属动漫头像
  15. LATEX编译出现Undefined control sequence.
  16. RocketMQ源码分析(十五)之文件恢复
  17. opencv保存视频编码方式
  18. 欠钱不还直接打,打到还钱才停
  19. 破解携程中文验证码爬取机票价格数据
  20. 纪念尼古拉·特斯拉---一个伟大却很少被普罗大众认识的科学家

热门文章

  1. 2006年下半年 网络工程师 上下午试卷【附带答案】
  2. 奇偶个数_只愿与一人十指紧扣_新浪博客
  3. OpenCV图像处理常用手段
  4. 【CV】PAA论文解读:在物体检测中利用概率分布来将anchor分配为正负样本
  5. 【OpenCV 4开发详解】图像二值化
  6. 【OpenCV 4开发详解】图像连接
  7. 【Smobiler企业APP开发之一】开发环境部署
  8. 【转】如何使用VS 2013发布一个可以在Windows XP中独立运行的可执行文件
  9. SharedPreferences的工具类,使用起来方便、快捷
  10. JSP HTML区别