圆方树
cpp
struct RoundSquareTree{
vector<vector<int>> G,adj;
vector<int> dfn,low;
int dfc,cnt,n;
int stk[N],top;
void init(int n){
this->n=n;
dfn.assign(n+1,0);
low.assign(n+1,0);
top=dfc=0;
G.assign(2*n+1,{});
adj.assign(n+1,{});
}
void tarjan(int u){
low[u]=dfn[u]=++dfc;
stk[++top]=u;
for(auto v:G[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
if(low[u]==dfn[u]){
++cnt;
int y;
do{
y=stk[top--];
G[cnt+n].push_back(y);
G[y].push_back(cnt+n);
}while(y!=v);
G[cnt+n].push_back(u);
G[u].push_back(cnt+n);
}
}
else low[u]=min(low[u],dfn[v]);
}
}
};