所谓圆方树,就是又圆又方的树
(逃)
前言
树有很多良好的性质,也可以上许多算法和数据结构
但我们对于一般图却没有太多办法…
然而,对于有些关注连同性、路径并&交的一般图问题,我们可以用圆方树,转化为树上问题解决。
解析
简介
把所有的点双求出来,然后把每个点双建成一个点(称为方点),向点双内的所有点(称为圆点)连边
实现
既然要求点双,当然要用tarjan啦
和普通的求tarjan求割点有一些区别:(越来越容易挂了)
- 不需要在函数里特判根(但是最后需要把残留在栈里的根弹掉)
- 求出点双弹栈时son和x不一定在栈里是相邻的(其实比较显然)
void tarjan(int x){
dfn[x]=low[x]=++tim;zhan[++top]=x;
for(int i=g1.fi[x];~i;i=g1.p[i].nxt){
int to=g1.p[i].to;
if(!dfn[to]){
tarjan(to);low[x]=min(low[x],low[to]);
if(low[to]==dfn[x]){
++tot;
g2.addline(tot,x);g2.addline(x,tot);
while(zhan[top]!=to){
int now=zhan[top--];++val[tot];
g2.addline(now,tot);g2.addline(tot,now);
}
int now=to;++val[tot];
g2.addline(now,tot);g2.addline(tot,now);
top--;
}
}
else low[x]=min(low[x],dfn[to]);
}
return;
}