zoukankan      html  css  js  c++  java
  • 【转载】深度优先搜索代码

    本文章代码中的图用邻接矩阵来表示,所以算法复杂度为O(V^2)。如果用邻接表来表示,那么算法的复杂度为O(V+E)。

    DFS可用来判断图中是否有环,展现无向图中的连通分支。
    通过DFS,形成一个由多棵深度优先树所组成的深度优先森林。将原先图中的边添加到该森林之后,可以将所有边定义为以下四类:
    1.    树边:森林中自带的边(即不在森林生成后,从原先图中添加的边)。
    2.    反向边:从某个节点指向祖先的边,包括自己指向自己。非森林自带的边。如果图中存在反向边,则表明存在环。
    3.    正向边:从某个节点指向后代的边,非森林自带的边。
    4.    交叉边:边的两端点之间没有祖先后代关系,非森林自带的边。


    在DFS过程中,可以对任意两点间的边进行分类,对于有向图和无向图,分类情况有所区别。
    有向图:
    1.    树边:当visit了节点u后,如果边(u, v)存在,且v为WHITE,则该边为树边。
    2.    反向边:当visit了节点u后,如果边(u, v)存在,且v为GREY,则该边位反向边。
    3.    正向边:当visit了节点u后,如果边(u, v)存在,且v为BLACK,StartTime[u] < StartTime[v] < EndTime[v] < EndTime[u],则边为正向边。
    4.    交叉边:当visit了节点u后,如果边(u, v)存在,且v为BLACK,StartTime[v] < EndTime[v] < StartTime[u] < EndTime[u],则边为交叉边。

    无向图:
    1.    树边:当visit了节点u后,如果边(u, v)存在,且v为WHITE,则该边为树边。
    2.    反向边:否则就是反向边。


    代码

    #include <iostream>
    #define MAXLENGTH 1000
    #define WHITE 0
    #define GREY 1
    #define BLACK 2
    using namespace std;
    //The color of node. They can be used to define the link type between two nodes. WHITE means the node has not been visited. Gray means the node has been searched but its descendants have not been not all visited. Black means that the node and its descendants have all been visited.
    int Color[MAXLENGTH];
    //the parent of node i
    int Parent[MAXLENGTH];
    //the first time to be visited
    int StartTime[MAXLENGTH];
    //the second time to be visited, after visiting the descendants.
    int EndTime[MAXLENGTH];
    //the node graph
    bool Graph[MAXLENGTH][MAXLENGTH];
    //count the time
    int time_count;
    void DFS_Visit(int, int, int);
    /**
     * @brief Dfs graph who has n nodes
     *
     * @param n: the nodes' number
     */
    void DFS(int n)
    {
        //initialization
        for (int i = 0; i < n; ++i)
        {
            Color[i] = WHITE;
        }
        time_count = 0;
        //start DFS visit. Some nodes may can't be visited if starts from some nodes, so loop to ensure that every node can be visited.
        for (int i = 0; i < n; ++i)
        {
            if (Color[i] == WHITE)
            {
                DFS_Visit(i, -1, n);
            }
        }
    }
    /**
     * @brief DFS visit node
     *
     * @param node: the node to be visited
     * @param parent: the parent of the node
     * @param n: the nodes number in the graph
     */
    void DFS_Visit(int node, int parent, int n)
    {
        Color[node] = GREY;
        Parent[node] = parent;
        StartTime[node] = time_count++;
        for (int i = 0; i < n; ++i)
        {
            if (Graph[node][i] && Color[i] == WHITE)
            {
                DFS_Visit(i, node, n);
            }
        }
        Color[node] = BLACK;
        EndTime[node] = time_count++;
    }
    /**
     * @brief Print the path from start to end
     *
     * @param end: the end node
     */
    void PrintPath(int end)
    {
        cout << "Show path from end to start" << endl;
        while (end != -1)
        {
            cout << end << " start-time:" << StartTime[end] << "   end-time:" << EndTime[end] << endl;
            end = Parent[end];
        }
    }
    int main()
    {
        int n;
        while (cin >> n, n != 0)
        {
            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    cin >> Graph[i][j];
                }
            }
            int end;
            DFS(n);
            while (cout << "Input the end node, -1 means no more search." << endl, cin >> end, end != -1)
            {
                PrintPath(end);
            }
        }
    }
  • 相关阅读:
    CSS使用
    html基础
    面对对象之@classmethod、@staticmethod用法
    验证金额价格的正则表达式
    webstorm 2017.2.2 license server
    Oracle 查询当前系统时间十分钟之前的记录,时间比较SQL
    AngularJS-自定义过滤器 ng-repeat 求和
    封装http请求键值对的js函数
    获取当前的日期时间的js函数,格式为“yyyy-MM-dd hh:mm:ss”
    将金额数字转换为大写汉字的js函数
  • 原文地址:https://www.cnblogs.com/hansongjiang/p/3981897.html
Copyright © 2011-2022 走看看