RT,这篇题解
我主要对主函数调用tarjan()提出质疑,因此在下面放两种实现调用tarjan()的代码:
for(register int i=1;i<=n;++i)
if(!dfn[i])tarjan(i,i);
然而,具体tarjan()函数实现如下:
void tarjan(int x,int father){
dfn[x]=low[x]=++nowtime;
s.push(x);
for(register int i=head[x];i;i=e[i].next){
int v(e[i].to);
if(!dfn[v]){
tarjan(v,i);
low[x]=Min(low[x],low[v]);
}else if(i!=(father^1))low[x]=Min(low[x],dfn[v]);
}
if(dfn[x]==low[x]){
++dcccnt;
int k;
do{
k=s.pop();
belong[k]=dcccnt;
}while(k!=x);
}
}
可以发现,tarjan()的第二个形参father表示到这个点的边,用来防止同一条边重复执行,但是主函数中调用时传的初始值为i,那么我思考是否存在一种特殊情况,即点的编号和边的编号相同,使tarjan误以为某条便已被询问而不再继续执行。