仙人掌 && 圆方树 && 虚树 总结

本文详细总结了图论中的三种数据结构:仙人掌、圆方树和虚树。仙人掌是一种特殊的图结构,适合处理环上的问题,如最大独立集和直径计算。圆方树是仙人掌的拓展,用于维护单点和点双信息。虚树则用于处理多组询问,通过构建新树来压缩路径信息,实现高效的动态规划。文章通过多个例题解析了这些数据结构的应用和实现细节。
摘要由CSDN通过智能技术生成

仙人掌 && 圆方树 && 虚树 总结

Part1 仙人掌

定义

仙人掌是满足以下两个限制的图:

  • 图完全联通。
  • 不存在一条边处在两个环中。

其中第二个限制让仙人掌的题做起来十分舒服。

仙人掌的基环DP

首先勾出一棵有根生成树。
那么树边上正常转移即可。
我们把返祖边形成的环归到环上深度最浅的点上,即环顶。
那么到环顶时,单独跑一遍关于环的\(DP\)即可。
一般写法为:

void dfs(RG int u,RG int From) {
    dfn[u] = low[u] = ++ oo ; fa[u] = From ; 
    for(RG int i = head[u] ; i ; i = t[i].next) {
        RG int v = t[i].to ; 
        if(!dfn[v]) dfs(v , u) , low[u] = min(low[u] , low[v]);
        else if(v != From) low[u] = min(low[u] , dfn[v]) ;
        if(low[v] > dfn[u]) 正常的树形DP(F(v) --> F(u))。
    }
    for(RG int i = head[u] ; i ; i = t[i].next)
        if(fa[t[i].to] != u && dfn[t[i].to] > dfn[u]) 基环DP(u,v)。
}

分清楚\(low\)\(dfn\)的含义即可。
由于记录了\(fa_u\),基环DP中的扣环也非常容易:

tot = 0 ;
for(RG int x = v; x ^ u; x = fa[x]) q[++tot] = x ;
q[++tot] = u ; 

例题

例一:BZOJ4316 小\(C\)的独立集

题意:求仙人掌的最大独立集。
题解:做一遍正常的树形\(DP\),遇到环则把环拉出来单独做一遍。

例二:BZOJ1023 SHOI2008仙人掌图

题意:求仙人掌的直径。
题解:
同样的做正常树形\(DP\),碰到环顶则把环拉出来。
问题变为在环上选两个点,使其权值与距离和最大。显然单调队列即可。

Part2 圆方树

概况

圆方树是基于仙人掌的一种特殊数据结构。
其中圆点即图中原来的点,方点则代表一个点双。
我们沿用上面处理仙人掌\(DP\)的做法。
如果是生成树上的边,则直接相连。
否则,把环抠出来,为这个环新建一个方点,将环上的点与此方点连边。
板子与上面的仙人掌DP基本一样就不放了。
那么我们就可以在圆点上维护原本图单点信息,方点上维护点双信息了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值