圆方树基础知识梳理

由于树有不具有环等性质,在树上处理信息往往比在图上处理信息更加方便。圆方树就是这样一种把图转换成树的方法/思想,由此达到更便捷地维护图上信息,处理图上问题的目的。

仙人掌

仙人掌是满足每条边处于不超过一个简单环的无向连通图。
image

圆方树

*这里讨论的圆方树为广义圆方树。
对于一个仙人掌,该仙人掌中原有的点称为圆点。任意选定一个圆点,钦定它为树根开始 dfs,找出图中的所有点双连通分量,对于每个点双连通分量,新建一个方点,将该方点与点双连通分量里的所有点连一条边,删除原图上的所有边,如此便能得到一个树形结构。这棵树叫做圆方树。求点双连通分量还是用 tarjan 算法,在此基础上稍作修改即可。
Code:

void tarjan(int u) { low[u] = dfn[u] = ++tim; s[++s[0]] = u; ++si; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].v; if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); if (low[v] == dfn[u]) { wgh[++cnt] = 0; for (int x = 0; x != v; --s[0]) { x = s[s[0]]; t[cnt].push_back(x); t[x].push_back(cnt); ++wgh[cnt]; } t[cnt].push_back(u); t[u].push_back(cnt); ++wgh[cnt]; } } else low[u] = min(low[u], dfn[v]); } }

显然,圆方树中方点与方点之间肯定没有边,圆点与圆点之间也肯定没有边。

既好想又好写,不是吗?然而它有什么用呢?

应用

仙人掌最短路:

多次询问仙人掌上两点 (u,v) 的最短路,要求路径是简单路径。

先考虑下在仙人掌上怎么从 u 走到 v:有树边就走树边,有环的话两个方向走都可以。因此先随便钦定一个根,对每个 u 记录一个 top[u] 表示从 u 走到 u 所在环的根节点的最短路径长度,大概搞搞就可以出答案了——当然,这个方法实现起来比较复杂,我们把这个想法搬到圆方树上试试看。

如果 uv 在圆方树上的 lca 是圆点的话,最短路显然就是二者树上的距离。
如果 uv 在圆方树上的 lca 是方点的话,设 fau 为他们 lca 的一个子节点,u 在 以 fau 为根的子树中,同理也设一个 fav。那么最短路就是 树上 ufau 的最短距离 + 树上 vfav 的最短距离 + 环上 favfau 的最短距离。

同时,在建圆方树的时候,我们也要维护一下树边的边权使得树上最短路等于原图中最短路的长度。如果一个圆点和一个方点相连,且圆点为方点的父节点,那么这条边的边权为 0,否则边权设为 top[u] 即可。


__EOF__

本文作者Never Gonna Give You Up!
本文链接https://www.cnblogs.com/CZ-9/p/17120411.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   腾云今天首飞了吗  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示