zoukankan      html  css  js  c++  java
  • 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”,同时兼具判断合法性的功能。

    代码实现

  • 相关阅读:
    mysql非安装包安装教程
    HTML和CSS <h1> --3-- <h1>
    HTML和CSS <h1> --2-- <h1>
    HTML和CSS <h1> --1-- <h1>
    软件工程之四则运算总结
    图论算法 有图有代码 万字总结 向前辈致敬
    【万里征程——Windows App开发】使用Toast通知
    【万里征程——Windows App开发】设置共享(共享源和共享目标)
    【万里征程——Windows App开发】如何使用粘贴板
    【万里征程——Windows App开发】在应用中集成搜索
  • 原文地址:https://www.cnblogs.com/linfangnan/p/12787696.html
Copyright © 2011-2022 走看看