[笔记] 圆方树
仙人掌
与圆方树的关系
圆方树最初是用来处理仙人掌问题的,但在处理某些问题时,也可以拓展到一般图。
定义
每条边在不超过一个简单环中的无向图。
相关问题
如果一个序列问题不够毒瘤,就上树,还不够,就上仙人掌。
不过这里只考虑一些基础的问题,一个共同的核心思想就是按照是否在环上来讨论。
注意注意代码实现中的处理方式。
void solve(int x, int y){
int len = dep[y] - dep[x] + 1;// 环的长度
/* do some thing */
}
void tarjan(int x){
dfn[x] = low[x] = ++tim;
for(int i = head[x]; i; i = e[i].nx){
int y = e[i].to; if(y == fa[x]) continue;
if(!dfn[y]){
fa[y] = x, dep[y] = dep[x] + 1;
tarjan(y), low[x] = min(low[x], low[y]);
if(low[y] > dfn[x]) /* 按照树边处理 */;
}else low[x] = min(low[x], dfn[y]);
}
for(int i = head[x]; i; i = e[i].nx){
int y = e[i].to;/* x 是环上最浅的点,y 是最深的点 */
if(fa[y] != x && dfn[y] > dfn[x]) solve(x, y);
}
}
ex:仙人掌相关问题的处理方法 by zhangche0526
圆方树的构建
对于每个点双,建立一个方点,与点双内的点连边。
void tarjan(int x){
dfn[x] = low[x] = ++tim, stk[++top] = x;
for(int i = head[x]; i; i = e[i].nx){
int y = e[i].to;
if(!dfn[y]){
tarjan(y), low[x] = min(low[x], low[y]);
if(low[y] >= dfn[x]){
++tot, Add(tot, x);
while(stk[top + 1] != y) Add(tot, stk[top]), --top;
}
}else low[x] = min(low[x], dfn[y]);
}
}