关于树形结构的一点东西
Posted clickidea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于树形结构的一点东西相关的知识,希望对你有一定的参考价值。
前言: 考试树形结构太频繁惹菜鸡钧钧屁也不会!(雾
1.树的直径:
众所周知的两种求法:
- 两遍\(dfs\):
信奥不需要证明
第一遍\(dfs\)搜到树的最深叶节点,然后把这个叶节点拎起来作为根再\(dfs\)到最深叶节点。
*最深
指按照边长算距离根节点最远。
代码:
void dfs_R1(int x, int fa, int depth)
if(depth > Max) Max = depth, Rs = x;
for(int i = head[x]; i; i = edg[i].nxt)
if(edg[i].v == fa) continue;
dfs_R1(edg[i].v, x, depth + edg[i].w);
void dfs_R2(int x, int fa, int depth)
if(depth > ans) ans = depth, Re = x;
for(int i = head[x]; i; i = edg[i].nxt)
if(edg[i].v == fa) continue;
dfs_R2(edg[i].v, x, depth + edg[i].w);
树形\(DP\)
对于每个节点,维护其子树中的最长链和次长链,设数组f[x][1]
表示最长链,f[x][2]
表示次长链。更新时,若“连接儿子的边\(+\)此儿子子树中的最长链”大于当前最长链,则当前最长链变为次长链,最长链变为连接儿子的边\(+\)此儿子子树中的最长链,若大于次长链小于最长链则只更新次长链。树的直径必然为某一节点子树中的最长链\(+\)次长链。
代码:void dp_R(int x, int fa) for(int i = head[x]; i; i = edg[i].nxt) if(edg[i].v == fa) continue; dp_R(edg[i].v, x); if(edg[i].w + f[edg[i].v][1] > f[x][1]) f[x][2] = f[x][1], f[x][1] = edg[i].w + f[edg[i].v][1]; else if(edg[i].w + f[edg[i].v][1] > f[x][2]) f[x][2] = f[edg[i].v][1] + edg[i].w; ans = max(f[x][1] + f[x][2], ans);
以上是关于关于树形结构的一点东西的主要内容,如果未能解决你的问题,请参考以下文章
MYSQL 查询树形结构数据,查询某个节点下的所有子节点数据。