zoukankan      html  css  js  c++  java
  • 算法导论图论深度优先搜索及课后题答案

    深度优先搜索

    1.深度优先搜索先辈子图

    Gπ=(V,Eπ),其中

    Eπ={(π[v] ,v): v属于V且π[v]!=NIL}

    2.加盖时间戳

    每个顶点v有两个时间戳,当顶点v第一次被发现时(置为灰色),记录第一个时间戳d[v];当顶点第二次被发现时,置第二个时间戳f[v]

    (灰色的都是栈里边的)

    3.对|V|中顶点的每一个,都对应一个发现事件和完成事件,每一个顶点u都有d[u]<f[u]。这些时间戳为1到2|V|之间的整数。顶点u在时刻d[u]之前为白色,在时刻d[u]与d[v]之间为灰色。在以后就变成黑色了

    4.time 是一个全局变量,用于记录时间戳,DFS时间复杂度O(V+E)

        DFS(G)

            For each vertex u 属于V[G]

                Do color[u]=white

                    π[u]=NIL

            time =0;

            for each vertex u 属于V[G]

                do if color[u]=white

                    then DFS-VISIT(u)

        DFS-VISIT(u)

            color[u]=gray

            timeßtime+1

            d[u]=time

            for each v 属于adj[u]

                do if color[v]=white

                    thenπ[v]=u

                        DFS-VISIT(v)

            color[u]=black

            f[u]ßtimeßtime+1

    5.深度优先搜索的性质

    (1) DFS中顶点v是u的后裔,当且仅当v是u为灰色时发现的

    (2)如果发现顶点u用左括号(u来表示,完成用右括号u)来表示,在各级括号正确嵌套的前提下,发现与完成时间的记载就是一个完善的表达式

    (3) 括号定理:在对一个(有向或无向)图G=(V,E)的任何深度优先搜索中,对于图中的任意两个顶点u,v下列三个条件仅有一个成立

        (a)区间[d[u],,f[u]]和区间[d[v],f[v]]是完全不相交的,v或u都不是对方的后裔

    (b)区间[d[u],f[u]]完全包含于区间[d[v],f[v]],且在深度优先树中u是v的后裔

    (c)区间[d[v],f[v]]完全包含于区间[d[u],f[u]],且在深度优先树中v是u的后裔

    (4) 后裔区间嵌套

    在一个有向或无向图G=(V,E)中,顶点v是顶点u的后裔,当且仅当d[u]<d[v]<f[v]<f[u]

    (5) 白色路径定理

    在一个有向或无向图G=(V,E)的深度优先森林中,顶点v是顶点u的后裔,当且仅当在搜索过程中与时刻d[u]发现u是,可以从顶点u除法,经过一条完全有白色顶点组成的路径到达v

    (6)u,v是一条

            a)树边或前向边,当且仅当d[u]<d[v]<f[v]<f[u]

            b)反向边,当且仅当d[v]<=d[u]<f[u]<=f[v]

            c)交叉边,当且仅当d[v]<f[v]<d[u]<f[u]

    6.对边的分类

    (1)树边:在深度优先森林Gπ总共的边,如果顶点v是探寻边(u,v)时首次被发现的,那么(u,v)就是一条树边

    (2)反向边:深度优先树中,连接顶点u到它的某一祖先的那些边。有向图出现的自环也是反向边

    (3)正向边:在深度优先搜索中,连接u和某个后裔的非树边(u,v)

    (4)交叉边:同一棵深度优先搜索树的两个顶点之间,条件是其中一个顶点不是另一个顶点的祖先。也可以在不同度优先搜索树之间的顶点之间

    7.对边分类的算法

    对于每一条边(u,v),当该边被第一次探寻到时,即根据所到达的顶点v的颜色来对该

    边进行分类

    (1)白色 表明它是一条树边

    (2)灰色 表明它是一条反向边

    (3)黑色 d[u]<d[v]则(u,v)就是一条正向边

    (4)d[u]>d[v]则(u,v)就是一条交叉边

    8.在对一个无向图G进行深度优先搜索时,G的一条边要么是树边,要么是反向边

    (不可能出现正向边和交叉边)(想想为什么)

    所以在无向图的的深度优先搜索中先发现(白色)的为树边

    后发现的(灰色)为反向边。另外,不可能发现黑色的点,想想为什么

    9.课后习题22.3-6

    DFS(G)

        For each vertex u in V

            color[u]=white

            pi[u]=nil

    time=0

    for each vertex u in V

    if color[u]=white

    DFS-Vist(u)

     

     

     

    DFS-Visit(u)

    color[u]=gray

    time++

    d[u]=time

    push(u)

    while stack not empty

        u=top()

        isleaf=true

        for each v int adj[u]

            if color[v]=white

    color[v]=gray

                pi[v]=u

                time++

                d[v]=time

                push(v)

                isleaf=false

                break;

            if isleaf=true

                color[u]=black

                time++

                f[u]=time

                pop()

     

    10.课后题22.3-7和22.3-8的反例

    11.课后题22.3-9

        DFS(G)

            For each vertex u 属于 V[G]

                Do color[u]=white

                    pi[u]=NIL

            timeß0

            for each vertex u 属于V[G]

                do if color[u]=white

                    then DFS-VISIT(u)

        DFS-VISIT(u)

            color[u]=gray

            d[u]ßtimeßtime+1

            for each vertex v 属于 adj[u]

                do if(color[u]=gray)

                    if directed(G) or v!=pi[u]

                        then print(u,v)"is a back-edge"

                    else if directed(G) and color[v]=BLACK

                        then if d[u]<d[v]

                            then print(u,v) "is a forward-edge"

                            else print(u,v)"is a cross-edge"

                    else if color[v]=white

                        then pi[v]ßu

                            print(u,v) "is a tree-edge"

                            DFS-VISIT(v)

    color[u]=black

    f[u]ßtimeßtime+1

    12.课后题22.3-10

        从w,u,v分别开始DFS

        

    13-课后题22.3-11

    DFS(G)

        For each vertex u 属于 V[G]

            Do color[u]=white

                pi[u]=NIL

        timeß0

        counterß0

        for each vertex u 属于 V[G]

            do if color[u]=white

                then counterßcounter+1

                    DFS-Visit(u,counter)

     

    DFS-VISIT(u,counter)

        color[u]=gray

        cc[u]=counter

        timeßtime+1

        d[u]ßtime

        for each v 属于 adj[u]

            do if color[v]=white

                then pi[v]ßu

                    DFS-VISIT(v,counter)

        color[u]=black

        f[u]ßtimeßtime+1

    14.课后习题22.3-12

    判断单连通图

    单连通图:对任意两个顶点u,v属于V,则至多只有一条从u到v的简单路径

    若为单连通图,u,v只能是树边和反向边,不能是前向边和交叉边

     

     

    DFS(G)

            timeß0

            For each vertex u属于V[G] //对每个顶点都判断是否是单连通

            Do

    {

    For each vertex v 属于V[G]

         {

            color[v]=white

            pi[v]=nil

    }

    DFS-VISIT(u)

    }

    Print "G is singly connected"

            

    DFS-visit(u)

    {

            color[u]=gray

            timeßtime+1

            d[u]ßtime

            for each v 属于adj[u]

                do if color[v]=white

                    then pi[v]=u

                        DFS-visit(v)

                else if color[v]=black

                    then print "G is not singlu connected"

                            return

            color[u]=black

            f[u]ßtimeßtime+1

    }

  • 相关阅读:
    跳出iframe
    leetcode 225. Implement Stack using Queues
    leetcode 206. Reverse Linked List
    leetcode 205. Isomorphic Strings
    leetcode 203. Remove Linked List Elements
    leetcode 198. House Robber
    leetcode 190. Reverse Bits
    leetcode leetcode 783. Minimum Distance Between BST Nodes
    leetcode 202. Happy Number
    leetcode 389. Find the Difference
  • 原文地址:https://www.cnblogs.com/inpeace7/p/2456614.html
Copyright © 2011-2022 走看看