基环树
定义
(图片来自这篇文章)
-
基环树: 有 \(n\) 个点 \(n\) 条边的连通图
-
外向树: 每个点出度为 \(1\)
- 内向树: 每个点入度为 \(1\)
找环
-
\(dfs\)
-
拓扑排序
-
并查集
-
...
一般处理方法
因题而异,一般有两种常用的
-
第一种是先断掉环边,把环上点当作根,处理每一棵子树,再在环上处理,可能需要环形 \(DP\)。
-
第二种是选择一条环边断掉,化成树上问题,可能需要枚举断边,或者换根 \(DP\)。
具体还是看题吧
例题
简要题解
考虑一条边链接的两个点不能同时选,随便找一条环边\(u - v\)断开,强制\(u\) 不选,强制 \(v\) 不选,两种情况取 \(max\)
求基环树森林的直径和,边带权
简要题解
只考虑一棵基环树
直径可能过环,也可能不过环,两种情况取最大值
把环找出来,先删去环边,找每棵子树的直径最大值
再考虑如果经过一段环边,那么就是经过环上两点的路径和这两个点子树内最长链之和的最大值
考虑如何处理这个环上问题
两点间距离快速求解需要前缀和,那么答案可以写成
\(max(len_i + len_j + sum_i - sum_j) (i > j)\)
也即
\(max(len_i + sum_i, len_j - sum_j) (i > j)\)
但是环上有两个方向呢?
你发现另一个方向其实就是
\(max(sum + len_i - sum_i, len_j + sum_j) (i > j)\)
取 \(len_i + sum_i\) 的最值和 \(len_i - sum_i\) 的最值即可
简要题解
\(m = n - 1\),是一棵树,直接排序后按照 \(dfs\) 序输出即可
\(m = n\),基环树,发现环边一定不会全走,可以枚举环边断开,比较字典序取最小的即可
- 加强版
\(n \leq 500000\)
简要题解
先考虑在树上怎么做
一个点会贡献到一条链上
树上差分
环上呢?
考虑每个点会贡献到环上的一段,仍然可以对环进行差分处理