树上统计问题

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

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

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

只要点数 \(n \ne 1\) ,这样删除就一定形成 \(k \ge 2\) 个连通块。设大小分别为 \(s_1\) , \(s_2\) , \(\ldots,s_k\)s ,那么答案就是 \(s_1 \times (n - s_1) + s_2 \times (n - s_2) + \ldots + s_k \times (n - s_k)\)

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

\(\bullet\) \(u\) 孤立点。构成 \(1\) 个连通块。

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

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

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

例题: P4630 [APIO2018] 铁人两项

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

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

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

【拓展】

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

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

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

题目还是等价于断开 \(u\) 的连边后 \(s\)\(t\) 不再联通。

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

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

\(tarjan\) 同时统计就可以啦。

posted @ 2023-10-10 16:33  xuantianhao  阅读(28)  评论(0)    收藏  举报