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

    }

  • 相关阅读:
    test
    结构体内存对齐
    单链表(指针的指针应用)
    C语言实现线程池
    线程私有数据和pthread_once
    fcntl函数
    同构树
    动态规划经典题
    DP--方格取数问题
    动态规划的基本模型
  • 原文地址:https://www.cnblogs.com/inpeace7/p/2456614.html
Copyright © 2011-2022 走看看