【筆記】圓方樹
1 定義
仙人掌: 所有邊都至多被包含在一個環中。
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 狹義