(code:)
void dfs_dfn(int x)
{
dfn[x]=++dfn_cnt;
id[dfn_cnt]=x;
for(int i=a.head[x];i;i=a.e[i].nxt)
{
int y=a.e[i].to;
if(dfn[y]) continue;
fa[y]=x;
dfs_dfn(y);
}
}
int find(int x)
{
if(x==fath[x]) return x;
int tmp=find(fath[x]);
if(dfn[sdom[val[fath[x]]]]<dfn[sdom[val[x]]])
val[x]=val[fath[x]];
return fath[x]=tmp;
}
void tarjan()
{
for(int i=1;i<=n;++i) sdom[i]=fath[i]=val[i]=i;
for(int i=dfn_cnt;i>1;--i)
{
int x=id[i];
for(int i=b.head[x];i;i=b.e[i].nxt)
{
int y=b.e[i].to;
if(!dfn[y]) continue;
find(y);
if(dfn[sdom[val[y]]]<dfn[sdom[x]])
sdom[x]=sdom[val[y]];
}
c.add(sdom[x],x);
fath[x]=fa[x];
x=fa[x];
for(int i=c.head[x];i;i=c.e[i].nxt)
{
int y=c.e[i].to;
find(y);
if(sdom[val[y]]==x) idom[y]=x;
else idom[y]=val[y];
}
c.head[x]=0;
}
for(int i=2;i<=dfn_cnt;++i)
{
int x=id[i];
if(idom[x]!=sdom[x])
idom[x]=idom[idom[x]];
}
for(int i=2;i<=n;++i) d.add(idom[i],i);
}