所谓圆方树,就是又圆又方的树
(逃)
前言
树有很多良好的性质,也可以上许多算法和数据结构
但我们对于一般图却没有太多办法…
然而,对于有些关注连同性、路径并&交的一般图问题,我们可以用圆方树,转化为树上问题解决。
解析
简介
把所有的点双求出来,然后把每个点双建成一个点(称为方点),向点双内的所有点(称为圆点)连边
实现
既然要求点双,当然要用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;
}