本文解决了三年以来的疑惑。
三年多来,我写树上dfs的时候只敢写void dfs()。因为每次我写int dfs()准出错。原因是因为:int dfs()是需要返回值层层上传的,而void dfs()搜到了答案那就记录下来。
首先来看代码「在树上求now到1的距离」(注意,这段代码是错误的树上dfs):
int dfs3(int now,int stp)
{
vis[1][now] = 1;
if(now==1)
{
return stp;
}
for(int i=0;i<tree[now].size();i++)
{
if(!vis[1][tree[now][i]])
{
vis[1][tree[now][i]] = 1;
return dfs3(tree[now][i],stp+1);
}
}
}
如果你没有发现这段代码的问题,那么你也跟我有一样的毛病,本文需要认真阅读,并且多加思考。
试想一下,如果当前搜到一条链,now在链上,但是节点1在now的父节点的另一个儿子的链上,以上这段代码还能搜到答案吗?答案是不能。因为以上的代码搜到这条链的叶子结点后,就无法继续搜索了。
如果答案不在当前的链上,那么永远都无法找到答案。
下面看另一段代码:
int dfs4(int now,int stp)
{
vis[2][now] = 1;
for(int i=0;i<tree[now].size();i++)
{
int nw = tree[now][i];
if(!vis[2][nw])
{
vis[2][nw] = 1;
if(nw==v) return stp+1;
else
{
int tmp = dfs4(nw,stp+1);
if(tmp!=-1) return tmp;
}
}
}
return -1;
}
这段代码与上面的代码有何不同?
这段代码我搜不到答案的时候会return -1,表示这条链上没有答案,并且在dfs的时候会判断当前这条链能不能搜到答案,如果不能搜到,那么直接换下一条链。
好好品味。