树上统计问题

在树上,对于每个点 u ,设 c(u) 为点对 (s,t) 的数量,满足 st ,且 st 的路径经过点 u

要求用总共 O(n) 的复杂度,求出 c 数组。

我们可以把要求的 c(u) 转化成:删除与点 u 相关联的所有边后,有多少个点对不再联通。

只要点数 n1 ,这样删除就一定形成 k2 个连通块。设大小分别为 s1 , s2 , ,sks ,那么答案就是 s1×(ns1)+s2×(ns2)++sk×(nsk)

给原树随便定个根,那么形成的连通块分别是:

u 孤立点。构成 1 个连通块。

u 的每个儿子对应的子树。一个儿子,对应一个子树,对应 1 个连通块。

u 的所有祖先。如果 u 不是根,这里就构成 1 个连通块。

树上一次 dfs ,上面三种连通块的大小都能很方便得到。于是做到总复杂度 O(n)

例题: P4630 [APIO2018] 铁人两项

该题先构建广义圆方森林,然后圆点设权 1 ,方点设权为点双连通分量的大小后,再乘上对应的 c(u) 求和为答案。

因为是广义圆方森林,应该对每棵树分别统计答案,将每棵树的大小作为上面的 n ,而不是总点数。

而且这个题要统计的 st 都要求是圆点,所以统计连通块大小时只应统计圆点。

【拓展】

在 无向图 上,对于每个点 u ,设 c(u) 为点对 (s,t) 的数量,满足 st ,且 st 的 所有路径 都经过点 u

要求用总共 O(n) 的复杂度,求出 c 数组。

其实就是这个题 P3469 [POI2008] BLO-Blockade

题目还是等价于断开 u 的连边后 st 不再联通。

这次,我们构建 dfs 搜索树,然后在树上 dfs ,接着沿用上面的做法。但是,删除点 u 的连边后,以 u 的某个儿子 v 为根的子树可能跟 u 的祖先是连着的。

所以当且仅当 dfn[v]low[u] 的时候,我们再将以 v 为根的子树当成一个连通块处理;否则,这个子树应该和 u 的祖先算在一个连通块中。

tarjan 同时统计就可以啦。

posted @   xuantianhao  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示