Determine whether a graph (undirected graph and directed graph) has loops

Source: Internet
Author: User

The source text is not found. Please refer to the link below:

Http://www.cnblogs.com/hiside/archive/2010/12/01/1893878.html

Http://topic.csdn.net/u/20071023/11/3edb81fc-37b2-4506-906e-44dc0fc521f2.html

1. undirected graph: Method 1:
  • If a loop exists, a subgraph is a loop. Degrees of all vertices in the loop> = 2.
  • N algorithm:

    Step 1: Delete all vertices with a degree <= 1 and related edges, and subtract one degree from other vertices related to these edges.

    Step 2: Enter the vertex whose degree is 1 into the queue and retrieve a vertex from the queue and repeat Step 1.

    If a vertex is not deleted, a ring exists; otherwise, no ring exists.

  • N algorithm analysis:

    There are m edges and N vertices.

    I) If M> = N, the existence of loops can be determined based on graph theory knowledge. (Proof: If there is no loop, the figure must be K trees K> = 1. Based on the nature of the tree, the number of edges M = n-k. K> = 1, so: m <n)

    Ii) If M is less than N, perform operations (n times at most) on each vertex whose degree is 0 according to the above algorithm ), or each time you delete a vertex with a degree of 1 (delete an edge at the same time), the operation is performed once (up to m times ). The total number of these two operations will not exceed m + n. Due to m <n, the algorithm complexity is O (n ).

  • Note:

    In this method, the algorithm complexity is more than O (V). When the degree of all vertices is calculated at the initial time, the complexity is (V + E), even if E> = V in subsequent cycles, the complexity of this algorithm can only be O (V + E ). Secondly, in each cycle, if the vertex with a degree of 1 is deleted, the degree of the vertex connected to the vertex must be reduced by one, execute delete node from list [list [node]. The search complexity here is the length of list [list [node, only in this way can we ensure that when degree [I] = 1, there is only one vertex in list [I. In this way, the worst complexity is O (EV.

    Method 2:

    DFS searches for a graph. the edge in the graph can only be a tree edge or a reverse edge. Once a reverse edge is found, it indicates that a ring exists. The complexity of this algorithm is O (V ).

    Method 3:

    From: http://blog.csdn.net/lzrzhao/archive/2008/03/13/2175787.aspx

    PS: This method was supplemented in

    Assume that the number of vertices in the graph is m and the number of edges is E.

    Traverse the graph and judge that the graph is divided into several parts (assuming the P part, that is, the graph has P connected components). For each connected component, if there is no ring, it can only be a tree, that is: number of edges = knots-1 as long as one of the satisfied edges> knots-1

    The source image has a ring.

    After adding the inequality of the connected components of P, we get: P1: e1 = M1-1P2: E2 = M2-1...PN: en> all edges of the MN-1 (e)> all knots (m) -Number of connected components (P)

    E + P> M. Therefore, if the result is e + P> m, the source image has a ring. Otherwise, the source image does not have a ring.

    The instance code is as follows:

    # Include <iostream> # include <malloc. h> using namespace STD; # define maxnum 100 // defines the maximum number of vertices that the neighboring area shows. Int visited [maxnum]; // uses the visited array to mark whether the vertex has been accessed, 0 indicates not accessed, 1 indicates that the accessed int dfs_count; // number of connected parts, used to test whether the undirected graph is connected, and dfs_count = 1 indicates that there is only one connected part, therefore, the entire undirected graph is a connected int pre [maxnum]; int post [maxnum]; int point; // pre and post values // The graph's Adjacent matrix represents the structure typedef struct {char V [maxnum]; // The graph's vertex information int e [maxnum] [maxnum]; // vertex information of the graph int vnum; // vertex count int Enum; // Number of edges} graph; void create Graph (graph * g); // create graph gvoid DFS (graph * g); // traverse graph gvoid DFS (graph * g, int I) first ); // from vertex I, the depth first traverses the adjacent vertex void DFS (graph * g, int I) {// cout <"vertex" <G-> V [I] <"accessed" <Endl; cout <"vertex" <I <"accessed" <Endl; visited [I] = 1; // mark vertex I accessed pre [I] = ++ point; For (Int J = 1; j <= G-> vnum; j ++) {If (G-> E [I] [J]! = 0 & visited [J] = 0) DFS (G, J);} post [I] = ++ point;} void DFS (graph * g) {int I; // initialize the visited array, indicating that all vertices have not been accessed for (I = 1; I <= G-> vnum; I ++) at the beginning) {visited [I] = 0; Pre [I] = 0; post [I] = 0;} // initialize pre and postpoint = 0; // The initial number of connected parts is 0dfs_count = 0; // The depth first searches for (I = 1; I <= G-> vnum; I ++) {If (visited [I] = 0) // If This vertex is accessed, the depth first traversal is performed from the I vertex {dfs_count ++; // count the number of times that void DFS (graph * g, int I) is called DFS (G, I) ;}} void creategraph (graph * g) // create graph G {cout <"creating undirected graph... "<Endl; cout <" Enter the number of vertices vnum: "; CIN> G-> vnum; cout <" Enter the number of edges Enum :"; cin> G-> Enum; int I, j; // enter vertex information // cout <"Enter vertex information:" <Endl; // for (I = 0; I <G-> vnum; I ++) // CIN> G-> V [I]; // initial drawing gfor (I = 1; I <= G-> vnum; I ++) for (j = 1; j <= G-> vnum; j ++) g-> E [I] [J] = 0; // condition of the input edge, cout <"Enter the header and end of the edge" <Endl; for (int K = 0; k <G-> Enum; k ++) {CIN> I> J; G-> E [I] [J] = 1; g-> E [J] [I] = 1; // undirected graph symmetry} int main () {graph * g; G = (graph *) malloc (sizeof (graph); creategraph (g); // create a graph gdfs (g); // drill-down traversal // number of connected parts, used to determine whether a connected graph cout <"number of connected parts:"; cout <dfs_count <Endl; If (dfs_count = 1) cout <"graph G is a connected graph" <Endl; else if (dfs_count> 1) cout <"graph G is not a connected graph" <Endl; // pre and post values for each vertex (INT I = 1; I <= G-> vnum; I ++) the pre and post of cout <"vertex" <I <"are:" <PRE [I] <"" <post [I] <Endl; // cout <Endl; // determines whether a ring if (G-> Enum + dfs_count> G-> vnum) exists in an undirected graph) cout <"graph G contains loops" <Endl; elsecout <"graph G does not contain loops" <Endl; int K; CIN> K; return 0 ;} /* input: Creating an undirected graph... enter the number of vertices vnum: 10 enter the number of edges Enum: 9 enter the edge header and tail 1 21 42 52 64 75 96 37 89 10 */

    Note: This method cannot be used for Directed Graphs. For example, 1-> 2, 1-3, 2-> 3, 4-> 5, if the above method is used, it is determined that the content is still included, but not so.
    Directed Graph:

    There are mainly methods in deep priority and topological sorting 2.

    1. Topology Sorting. If you can sort all nodes in the graph by Topology Sorting, it means there is no ring in this graph, and if it cannot be completed, it means there is a ring.

    2. You can use stronugly connected components to do this. We can recall the concept of strongly connected subgraphs, that is, for a subgraph of a graph, any U-> V in the subgraph, A strongly connected subgraph must be V-> U. This limitation is exactly the concept of the ring. Therefore, I think the method of searching for Strongly Connected subgraph of a graph should be able to find out whether there are loops and several loops in the graph.

    3. Use an improved DFS

    When I first saw this problem, I wanted to solve it simply by using DFS. However, I cannot think about it. If the question shows an undirected graph, OK and DFS can solve the problem. However, undirected graphs do not produce correct results. For example, a-> B, A-> C-> B, we use DFS to process this graph and we will find that it has a ring, but it does not.

    We can slightly change the DFS to solve this problem. The solution is as follows:

    A node in the figure has three states based on its C [N] value:

    0, this node has not been accessed

    -1: The child node is being accessed at least once.

    1. Its child nodes have been accessed.

    Based on this assumption, when searching by DFS, there are three possibilities for a node:

    1. If C [v] = 0, this is a new node and is not processed.

    2. If C [v] =-1, it indicates that the node itself is accessed when the child of the node is accessed, then there is a ring in the figure.

    3. If C [v] = 1, similar to the derivation of 2, there is no ring. Add some special processing in the program, that is, you can find several rings in the figure and record the path of each ring.

    PS: This code was implemented on

    Code example for improving the DFS algorithm (determining whether it is a directed acyclic graph)

    # Include <iostream> # include <malloc. h> using namespace STD; # define maxnum 100 // defines the maximum number of vertices in the adjacent area int pre [maxnum]; int post [maxnum]; int point = 0; // pre and post values: bool is_dag = true; // identification space, indicating directed acyclic graph/* vertex color table color [u] 0 white, the unaccessed nodes are marked with white-1 gray, and the nodes that have been accessed once are marked with gray-1 black. When all future generations of the nodes are accessed, the nodes are marked with black reverse edges: if V is gray during the first access (u, v), (u, v) is the reverse side. If no reverse edge is found in the depth-first search of a graph, no loop program is used to determine the basis for this graph: it is still based on the node depth traversal of the graph. When V is accessed, if V is accessed, there are two statuses: Color [u] =-1, the program jumps out, And the loop color [u] = 1 exists. The program continues, this is not the cycle time complexity: O (N + E) */INT color [maxnum]; // vertex color table color [u] // graph's Adjacent matrix represents the structure typedef struct {char V [maxnum]; // graph's vertex information int e [maxnum] [maxnum]; // vertex information of the graph int vnum; // vertex count int Enum; // Number of edges} graph; void creategraph (graph * g ); // create graph gvoid DFS (graph * g); // traverse graph gvoid DFS (graph * g, int I) in depth first ); // from vertex I, the depth first traverses the adjacent vertex void DFS (graph * g, int I) {// cout <"vertex" <G-> V [I] <"accessed" <Endl; cout <"vertex" <I <"accessed" <Endl; color [I] =-1; Pre [I] = ++ point; for (Int J = 1; j <= G-> vnum; j ++) {If (G-> E [I] [J]! = 0) {If (color [J] =-1) // find the back edge, with the ring {is_dag = false; // not directed acyclic graph} else if (color [J] = 0) DFS (G, j) ;}} post [I] = ++ point; color [I] = 1; // indicates that all descendant nodes of I have been accessed} void DFS (graph * g) {int I; // initializes the color array, indicates that all vertices have not been accessed at the beginning, // initialize pre and postfor (I = 1; I <= G-> vnum; I ++) {color [I] = 0; Pre [I] = 0; post [I] = 0;} // depth-first search for (I = 1; I <= G-> vnum; I ++) {If (color [I] = 0) // If This vertex is accessed, then, starting from vertex I, the depth first traversal {DFS (G, I) ;}} void creategraph (graph * g) // create graph G {cout <"creating undirected graph... "<Endl; cout <" Enter the number of vertices vnum: "; CIN> G-> vnum; cout <" Enter the number of edges Enum :"; cin> G-> Enum; int I, j; // gfor (I = 1; I <= G-> vnum; I ++) for (j = 1; j <= G-> vnum; j ++) g-> E [I] [J] = 0; // condition of the input edge cout <"Enter the edge header and end" <Endl; For (int K = 1; k <= G-> Enum; k ++) {CIN> I >> J; G-> E [I] [J] = 1 ;}} int main () {graph * g; G = (graph *) malloc (sizeof (graph); creategraph (g); // create a graph gdfs (g ); // depth-first traversal // pre and post values of each vertex for (INT I = 1; I <= G-> vnum; I ++) the pre and post of cout <"vertex" <I <"are:" <PRE [I] <"" <post [I] <Endl; // determine whether a directed acyclic graph if (is_dag) cout <"Figure G shows a directed acyclic graph without loops" <Endl; elsecout <"Figure G does not have a directed acyclic graph with a ring" <Endl; int K; CIN> K; return 0;}/* input 1: creating undirected graph... enter the number of vertices vnum: 3 enter the number of edges Enum: 3 enter the edge header and tail 1 21 33 2 input 2: Creating an undirected graph... enter the number of vertices vnum: 4 enter the number of edges Enum: 4 enter the edge header and tail 1 22 33 44 2 */

    This article Reprinted from: http://www.cnblogs.com/xwdreamer/archive/2011/06/11/2297008.html

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.