简体   繁体   中英

Count number of cycles in a Directed graph

Question:

Write a program which gives us the number of cycles in a Directed graph.

My approach:

I know that we can detect cycles in graph using Depth First Search and return the answer in terms of a simple boolean value. I have written a code for this below. However, I am trying to implement a counter in this code which increments every time a cycle is detected. But I don't seem to get the right answer no matter where I implement the counter! (I've written the increment statements in comments)

I am also worried that DFS is not the right approach to chose for this question because there might be some common edges between the cycles.

The cycle detection algorithm is taken from: https://www.geeksforgeeks.org/detect-cycle-in-a-graph/

The code given below, produces an output:

在此处输入图片说明

for the graph:

在此处输入图片说明

(Here it says 0 cycles, because of the commented count is incremented)

Code:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

class Graph 
{   
    static int count = 0; //counter initialised
    private final int V;
    private final List<List<Integer>> adj;

    public Graph(int V)
    {
        this.V = V;
        adj = new ArrayList<>(V);
        
        for (int i = 0; i < V; i++)
            adj.add(new LinkedList<>());
    }
    
    private boolean isCyclicUtil(int i, boolean[] visited,boolean[] recStack)
    {
        if (recStack[i])
            return true; //count++;

        if (visited[i])
            return false;
            
        visited[i] = true;

        recStack[i] = true;
        List<Integer> children = adj.get(i);
        
        for (Integer c: children)
            if (isCyclicUtil(c, visited, recStack))
                return true; 
                
        recStack[i] = false;

        return false;
    }

    private void addEdge(int source, int dest) {
        adj.get(source).add(dest);
    }
    
    private boolean isCyclic()
    {
        boolean[] visited = new boolean[V];
        boolean[] recStack = new boolean[V];
        for (int i = 0; i < V; i++)
            if (isCyclicUtil(i, visited, recStack))
                return true; //count++;
        return false;
    }
    
    public static void main(String[] args)
    {
        Graph graph = new Graph(4);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 2);
        graph.addEdge(2, 0);
        graph.addEdge(2, 3);
        graph.addEdge(3, 3);
        
        if(graph.isCyclic())
            System.out.println("Graph contains cycles");
        else
            System.out.println("Graph doesn't contains "+count+" cycles");
    }
}

I think the problem is that a single node can be part of more than just one circle, and you set to "visited" after the first one. I would use DFS, and a backtracking algorithm afterwards to find the number of circles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM