圆方树

创建时间:2025-10-03


圆方树(Block forest)是一种将无向图转化为树的工具,从而使两点路径唯一,以快速解决图中计数等问题。

圆方树的构建用到了点双连通分量的知识。为每个点双连通分量创建一个虚点,称之为方点,同时保留原图所有点,称之为圆点。每个方点与其所对应的原图中的点双连通分量中每个点对应的圆点连边,这样圆方树就建成了。

以下面这张图为例建圆方树。

显然,原图中有 \(3\) 个点双连通分量,分别为 \(\{1,2,3\},\{3,4\},\{3,5\}\),为这 \(3\) 个点双连通分量建方点,并向圆点连边,得到圆方树如下:

类比点双连通分量求法写出圆方树建发:

void Tarjan(int u) {
	stk.push(u);
	dfn[u] = low[u] = ++tim;
	for (int v : g[u])
		if (!dfn[v]) {
			Tarjan(v);
			low[u] = min(low[u], low[v]);
			if (dfn[u] <= low[v]) {
                e[u].push_back(++tot);
				while (stk.top() != v) {
					e[tot].push_back(stk.top());
					stk.pop();
				}
                e[tot].push_back(v);
				stk.pop();
			}
		} else
			low[u] = min(low[u], dfn[v]);
}

int main() {
    ...
    tot = n;
    for (int i = 1; i <= n; i++)
        if (dfn[i]) {
            Tarjan(i);
            stk.pop();
        }
    ...
}

很容易发现圆方树的很多性质:

  1. 圆点和圆点之间没有边,方点和方点之间没有边。
  2. 圆方树的点数严格小于 \(2n\)
  3. 圆方树两方点间要么没有点,要么是一个原图的割点。

圆方树的应用:

P4630 [APIO2018] 铁人两项
P4320 道路相遇
UVA1464 Traffic Real Time Query System
SP2878 KNIGHTS - Knights of the Round Table
P4606 [SDOI2018] 战略游戏
P5236 【模板】静态仙人掌

posted @ 2026-06-02 16:25  xubaichuan  阅读(7)  评论(0)    收藏  举报