树形dp ---- 树形换根dp F - The Maximum Subtree
题目链接
题目大意:
给定一颗树,求这个树的最大子树,且这个子树是一个good-tree。
good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交
解题思路:
- 根据线段相交,假设以rootrootroot节点为根,那么我们可以选择两条棵子树进行向下递归继续选择,其他的儿子节点只能选自己,因为线段只有两端向外延伸
- 如果不是根节点那么我们只能选一个子树向下延伸,其他都是只能直接选儿子
- 那么我们就是要枚举所以点为根去dp,然后更新答案
- 但是这样会超时,那么我们就要进行换根dp!
- 我们看看要保存什么记录?
- 对于每个点我们要记录下面的最大值和次大值的子树,那么我们就选这两个子树进行延伸,其他就直接选。
- 换根的时候我们要看看看当前点和根节点之间的关系?
- 如果根节点的最大值和次大值里面有一个来着你,那么你就选另一个!
- 然后再更新你自己的次大值和最大值就可以了
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相关推荐
- 树形(dp+换根dp)
普通树形dp 树形dp通常围绕根节点来写状态转移方程 用一道基础的树形dp例题来具体分析: 没有上司的舞会 Ural 大学有 N 名职员,编号为 1∼N. 他们的关系就像一棵以校长为根的树,父节点就是 ...
- 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 ...
- 2020牛客多校第一场B虚树+质数筛+换根dp
题目大意: 1.可以发现阶乘增长是很快的所以你要把整颗树建立出来是不实际的. 2.我们可以假设这棵树已经建出来出来了我们应该怎么搞 首先很明显是一个树形dp, 我们设dp[j],是以j为u到其他点距离 ...
- 小G砍树 (换根dp)
小G砍树 给你一棵n个节点的带标号无根树.每次,你可以选择一个度数为1的节点并将它从树上移除.问总共有多少种不同的方式能将这棵树删到只剩 1 个点.两种方式不同当且仅当至少有一步被删除的节点不同. 思 ...
- Hile每日算法-3.31-树形dp之换根法
树形dp之换根法 周二周三真的太难了,有早课导致不能熬夜,于是就只能趁着中午的时间写一写,这几天先写点简单的东西,就当重新复习了,应该算是给初学者的知识普及,其他的过了周三再说. 首先来讲一下树的重心 ...
- 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)
题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...
- BZOJ 2159 「国家集训队」Crash 的文明世界(第二类斯特林数,换根DP)【BZOJ计划】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2159 是 hydro 的 BZOJ ...
- 换根dp求树所有节点的最小深度
链接:https://ac.nowcoder.com/acm/contest/18072/A 牛妹有一张连通图,由n个点和n-1条边构成,也就是说这是一棵树,牛妹可以任意选择一个点为根,根的深度为0, ...
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
最新文章
- Android调用前置摄像头的方法
- IBatis常见错误集锦
- 试分析下列程序段:请选择(L1、L2、L3或L4)填入相应的括弧中
- 处理自己的数据集_手写代码实现KDD CUP99数据集的数据归一化处理
- IDEA编译通过能运行但是出现红色下划线
- 循环计数_FOR 循环
- 设计糟糕的 RESTful API 就是在浪费时间!
- IPS不用添加service帐号进入linux使得管理主机能访问的方法
- Linux 命令(113)—— seq 命令
- 2015-02-10
- 松下新一代电力线通信(PLC)技术经IEEE P1901.3工作小组批准成为基准规范
- 2018.11.05._PYTHN_DJANGO_CLASS 144~CLASS147
- 80后小学计算机课上的游戏,80后最值得回味的经典课间游戏
- AI绘图第二弹!绘制专属动漫头像
- LATEX编译出现Undefined control sequence.
- RocketMQ源码分析(十五)之文件恢复
- opencv保存视频编码方式
- 欠钱不还直接打,打到还钱才停
- 破解携程中文验证码爬取机票价格数据
- 纪念尼古拉·特斯拉---一个伟大却很少被普罗大众认识的科学家