PTA习题解析——判断DFS序列的合法性

情景需求

测试数据

输入样例

6 9
0 1
0 2
0 3
2 1
3 2
4 2
1 4
2 5
4 5
4
0 1 4 2 5 3
0 2 5 1 4 3
0 2 3 1 4 5
3 2 5 1 4 0

输出样例

Yes
Yes
No
Yes

情景解析

也就是说,对于顶点而言我们并不关心顶点的顺序,因为这是一个一对多的关系,我们没有手法去强行规定他们的先后序。因此对于图结构的 DFS,可能会产生不只一个的结果序列,例如从 0 号顶点出发,“ 0 1 4 2 5 3 ” 和 “ 0 2 5 1 4 3 ”都可以认为是正确的序列。
从上文所述,我们明白了这道题是不能够直接去 DFS 得到序列进行单模匹配的,也就是说不能用单纯的验证法去证明序列的正误。什么样的思路是可行的?正着做不行那就反着来,用反证法来实现,即我假设给出的序列是正确的,那么我按照你的序列来遍历应当是正确的,如果能够完成遍历那就说明序列正确,若在任何一个地方发生错误以至于无法 DFS,那就说明序列错误。
根据分析,我称之为“定向的 DFS”,即我虽然是按照 DFS 的模式去找这个序列,但是我的操作是受限的——根据给出的顺序遍历。因此我根据往下深度搜索时需要把已知的序列传递下去,为了使得提取边的信息更为方便,我选择邻接矩阵来存储图结构。

注意事项

由于要模拟 DFS,我们还是要使用递归,由于数据是受限的,因此递归的接口的正确性需要保证。这里给出 2 个卡了我 4 天的关键点:

  1. 由于图可能是非连通图,因此在最外层还需要加一个循环,放置单个路径挖掘完毕后,后续还有一个独立开来的图结构;
  2. 递归 DFS 就免不了回溯,此时必须保证回溯的接口的各个参数都是正确的,否则一旦遇到稠密图需要回溯时,可能就会因为参数的错误访问了不该访问的结点。

模拟验证

Yes 样例

假设验证序列 “ 0 1 4 2 5 3 ”,首先我们进入顶点 0:

根据序列,接下来我要去找顶点 1,路径可走:

根据序列,接下来我要去找顶点 4,路径可走:

根据序列,接下来我要去找顶点 2,路径可走:

根据序列,接下来我要去找顶点 5,路径可走:

根据序列,接下来我要去找顶点 3,路径不存在,这是由于顶点 5 没有指向其他顶点导致的。这个时候我们就回溯




我们发现,回溯到 0 号顶点时,有路径通向 3 号顶点,遍历继续。

经检验,该 DFS 序列正确。

No 样例

假设验证序列 “ 0 2 3 1 4 5 ”,我们跳到第二步:

根据序列,接下来我要去找顶点 3,路径不存在。但是这个时候,顶点 2 是存在向下深度搜索的路径的,分别是“ 2->1 ” 和 “ 2->5 ”,这就说明了序列是错误的。

伪代码

judgeDFS 函数

该函数是个递归函数,用于执行所谓的“定向的 DFS”,同时兼具判断合法性的功能。

代码实现

猜你喜欢

转载自www.cnblogs.com/linfangnan/p/12787696.html