关于基环树的一切
观前须知
笔者的博客主页
声明
本文使用 CC BY-NC-SA 4.0 许可。
本文为笔者在 OI 学习中的复习向学习笔记。
部分内容会比较简略。
如有好的习题会不断补充。
知识简介
定义
基环树是一个有
因为树有
所以基环树可以看作是加了一条边的树。
那么也就是加了个环的树。
注意:题目中给
后一种情况分连通分量分别做即可。
如图:
拓扑排序找环
无向图:
不断地删除 1 度点,直到留下的全部都是 2 度点,即为环。
有向图:
同上,只不过每次删入度为 0 的点。
DFS找环
无向图:
走的时候记 dfn 和 fa,
遇到遍历过且 dfn 大的点(防止重复计算),
就不断跳 fa 并记录。
代码:
void Dfs(int u) {
dfn[u] = ++Time;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].v;
if (v == fa[u]) continue;
if (!dfn[v]) { fa[v] = u, Dfs(v); }
else {
if (dfn[v] < dfn[u]) continue;
loop[++cnt] = v;
while (v != u) loop[++cnt] = v = fa[v];
}
}
}
有向图:
如果边指向叶子可以反过来。
边指向根的树只需要不断向上跳 fa,同时打标记,
直到跳到树的根后,再跳到的点已经打过标记了,那么就找到环了。
(如果要树型DP的话可以再建个反向图,就不用建双向图了)
代码:
while (!vis[x]) vis[x] = true, x = fa[x];
int v = x;
while (v != x) loop[++cnt] = v = fa[v];
基环树常见问题处理方式
把环断开,发现图变成了若干个森林。
那么可以把基环树看作用一个环连接着的若干棵树。
这时候就可以先断环,然后再树型DP了。
特别地,有些题涉及到树之间经过环的转移。
这类问题可以分类讨论成不经过环的和经过环的分别处理。
由于有环的出现,破环为链也比较常用。
习题
Luogu P2607 【ZJOI2008】 骑士
首先这个东西显然可以树型DP做。
但是这里是个基环树森林。
发现对于环的任意两个相邻点只能二选一或都不选。
那么任取环上的两个点分别做树型dp取
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!