【筆記】圓方樹

CloudWings發表於2024-07-17

【筆記】圓方樹

1 定義

仙人掌: 所有邊都至多被包含在一個環中。

image


2 構建

給一個點和它所在的所在的所有點雙連邊,同時,我們定義方點為虛點(即表示點雙的點),圓點為原圖上的點。

注意,是所有點雙,所以一個割點會連向多個點雙。同時,由定義得,該圖有且僅有圓方邊,因為圓圓邊可以繼續縮點。

既然是點雙,那麼我們就用 tarjan 實現即可。同時,在圖不連通的時候,構成的是圓方森林,此時每一個連通子圖就是一個圓方樹,所以我們就考慮原圖的連通子圖即可。

然後呢,類似地,我們可以像求強聯通分量一樣,選擇一個代表結點,作為此時的代表結點。對於這個點雙連通分量的縮點,我們可以容易發現此時 u 即為這個點雙聯通分量的代表點,並且 u 和 v 屬於同一個點雙聯通分量。

2.1 廣義

廣義圓方樹的一個性質:所有的圓點的父親一定是方點。

void tarjan (int u) {
	st.push(u), low[u] = dfn[u] = ++_dfn;
	for (int v : G[u])
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
			if (low[v] >= dfn[u]) {
				++_id; static int t;
				while (t != v)  // 這個地方 do-while 或 while 都可
					t = st.top(), st.pop(),
					tr[_id].push_back(t),
					tr[t].push_back(_id);
				tr[_id].push_back(u),
				tr[u].push_back(_id);
			}
		} else
			low[u] = min(low[u], dfn[v]);
}

2.2 狹義


3 應用 - 原方樹上 DP

相關文章