简体   繁体   中英

Detect cycle in an undirected graph

In order to detect cycle in undirected graph, following code anf algorithm are given; I am using normal Breadth First traversal along with slight modifications:

void bfsUtil(int s,vector<bool> &visited,vector<int> adj[],vector<int> &visits) {
    queue<int> q;
    q.push(s);
    visits[s]++;
    visited[s]=true;
    while(!q.empty()) {
        int vertex=q.front();
        q.pop();
        for(int i=0;i<adj[vertex].size();i++) {
            if(!visited[adj[vertex][i]]) {
                visited[adj[vertex][i]]=true;
                q.push(adj[vertex][i]);
                visits[adj[vertex][i]]++;
            } else {
                visits[adj[vertex][i]]++;
            }
        }
    }

}

/* This function is used to detect a cycle in undirected graph
*  adj[]: array of vectors to represent graph
*  V: number of vertices
*/
bool isCyclic(vector<int> adj[], int V)
{
   vector<int> visits(V,0);
   vector<bool> visited(V,false);
   for(int i=0;i<V;i++){
       if(!visited[i]) {
          bfsUtil(i,visited,adj,visits);
       }
   }
   for(int i=0;i<visits.size();i++) {
       if(visits[i]>2) {
           return true;
       }
   }
   return false;
}

Algorithm:

    1. Normal Breadth first search and maintaining a count aray for the no of visits of each vertex.
    2. If no of visits>2 
             print cycle is present 
        else
             print no cycle

But i am getting wrong anwer for below test case:

Input:
46 45
0 44 1 23 1 35 1 37 1 38 2 20 2 35 3 13 4 44 5 21 5 36 6 41 7 8 8 18 9 17 9 41 9 45 10 13 10 21 10 33 10 34 10 39 10 42 11 17 12 24 13 44 14 19 15 25 16 34 18 24 19 25 21 24 21 26 22 37 23 28 25 31 25 35 25 40 25 41 25 44 27 43 27 44 29 40 30 34 32 33

Its Correct output is:
0

And Your Code's output is:
1

Where is my algorithm going wrong?

Your algorithm is wrong. consider a graph of the following edges:

0 - 1
0 - 2

When the current node is 1, it also checks 0 as there is an edge from 1 to 0 too. so it will increment the visits count of 0. Similarly, 2 will also increment the count. So your code will always detect cycles wrongly.

To resolve this, you should keep a parent node for each node, from where the node is visited. When you are checking, you should never consider the edge to the parent. And finally, you don't need the visits array. If you find an adjacent node that is not parent of current node, but is still visited before, then you can conclude that there is a cycle.

Modifying your code:

bool bfsUtil(int s,vector<bool> &visited,vector<int> adj[],vector<int> &parent) {
    queue<int> q;
    q.push(s);
    visited[s]=true;
    while(!q.empty()) {
        int vertex=q.front();
        q.pop();
        for(int i=0;i<adj[vertex].size();i++) {
            if(adj[vertex][i] == parent[vertex])
                continue;
            if(!visited[adj[vertex][i]]) {
                visited[adj[vertex][i]]=true;
                q.push(adj[vertex][i]);
                parent[adj[vertex][i]] = vertex;
            } else {
                //cycle detected;
                return true;
            }
        }
    }
    return false;
}

/* This function is used to detect a cycle in undirected graph
*  adj[]: array of vectors to represent graph
*  V: number of vertices
*/
bool isCyclic(vector<int> adj[], int V)
{

   vector<bool> visited(V,false);
   vector<int> parent(V, -1); // -1 means no parent assigned
   for(int i=0;i<V;i++){
       if(!visited[i]) {
          if(bfsUtil(i,visited,adj,parent)) return true;
       }
   }

   return false;
}

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