这题是真的。。不会。我的疑惑点主要在于两个相邻dfs数关系的多样性,因此中间我一直想枚举暴搜,发现不会写代码。然后注意到遍历一定是从小到大的,又不会利用这个性质。。总之心态彻底被搞崩了,主要还是太菜。
题目描述:https://vjudge.net/problem/UVA-10410
网上比较详细的解释:https://www.cnblogs.com/jerryRey/p/4622927.html
核心思想主要是在等效吧,在dfs序与bfs序中同时相邻的情况中,兄弟关系与父子关系是等效的,此时就可以通过从小到大的遍历顺序判断关系。
dfs和bfs定义为在序列中的位置。
设当前节点为u,下一个结点为v。关系如下:
可以看到后两种情况在bfs序相邻时重叠了。但事实上做任一种情况处理都是等效的,因为在v为u的子结点且u,v在bfs序中相邻的情况下,u前面的兄弟结点已经完成了遍历(或者说都是叶子结点,因为如果它们仍有子结点,则在u这一层遍历完时,第一个遍历的数不应是v,而应是u这一层的结点第一个子结点),且u是这一层的最后一个结点,事实上此时整棵树只有u还能继续向下一层扩展,接下来遍历得到的序列是整个序列的最后一部分,因此就算把v看作是u的第一后兄弟结点(相当于把v所对应的子树移到了上一层的最后,也就是u后面),因为v对应的子树的dfs和bfs序不会改变,整个序列也不会改变。
得到这个结论,我们发现只要在bfs(v)=bfs(u)+1时判断一下v是否大于u就可以了,如果是,则可以做兄弟结点,如果否,则一定是子结点。
另外还学到了一点,就是可以在读入时预处理出每个编号所对应的序列中的位置,直接用数组存就好了,不用再找。
代码参考所引博客中的代码。tql
原文地址:https://www.cnblogs.com/jionkitten/p/12320995.html